Libraries refactor and add some sinks #4
|
@ -65,6 +65,9 @@ class Agora(object):
|
|||
def set_tx(self, tx):
|
||||
self.tx = tx
|
||||
|
||||
def set_notify(self, notify):
|
||||
self.notify = notify
|
||||
|
||||
def setup_loop(self):
|
||||
"""
|
||||
Set up the LoopingCall to get all active trades and messages.
|
||||
|
@ -470,12 +473,13 @@ class Agora(object):
|
|||
# Don't waste API rate limits on setting the same margin as before
|
||||
if new_margin != our_margin:
|
||||
# rtrn = self.agora.ad_equation(ad_id, new_formula)
|
||||
to_update.append([ad_id, new_formula, asset, False])
|
||||
to_update.append([ad_id, new_formula, asset, currency, False])
|
||||
# if not rtrn["success"]:
|
||||
# self.log.error("Error updating ad {ad_id}: {response}", ad_id=ad_id, response=rtrn["response"])
|
||||
self.log.info("Rate for {currency}: {margin}", currency=currency, margin=new_margin)
|
||||
else:
|
||||
self.log.info("Not changed rate for {currency}, keeping old margin of {margin}", currency=currency, margin=our_margin)
|
||||
print("TO UPDATE", to_update)
|
||||
self.slow_ad_update(to_update)
|
||||
|
||||
def slow_ad_update(self, ads):
|
||||
|
@ -487,15 +491,18 @@ class Agora(object):
|
|||
iterations = 0
|
||||
throttled = 0
|
||||
assets = set()
|
||||
while not all([x[2] for x in ads]) or iterations == 1000:
|
||||
currencies = set()
|
||||
while not all([x[4] for x in ads]) or iterations == 1000:
|
||||
for ad_index in range(len(ads)):
|
||||
ad_id, new_formula, asset, actioned = ads[ad_index]
|
||||
ad_id, new_formula, asset, currency, actioned = ads[ad_index]
|
||||
print("SLOW ITER", ad_id, new_formula, asset, currency, actioned)
|
||||
assets.add(asset)
|
||||
currencies.add(currency)
|
||||
self.log.error("ASSET {a}", a=asset)
|
||||
if not actioned:
|
||||
rtrn = self.agora.ad_equation(ad_id, new_formula)
|
||||
if rtrn["success"]:
|
||||
ads[ad_index][2] = True
|
||||
ads[ad_index][4] = True
|
||||
throttled = 0
|
||||
self.log.info("Successfully updated ad: {id}", id=ad_id)
|
||||
continue
|
||||
|
@ -518,8 +525,13 @@ class Agora(object):
|
|||
self.log.info("Slow ad update finished, no ads to update")
|
||||
self.irc.sendmsg("Slow ad update finished, no ads to update")
|
||||
else:
|
||||
self.log.info("Slow ad update completed with {iterations} iterations: [{assets}]", iterations=iterations, assets=assets)
|
||||
self.irc.sendmsg(f"Slow ad update completed with {iterations} iterations: [{assets}]")
|
||||
self.log.info(
|
||||
"Slow ad update completed with {iterations} iterations: [{assets}] | [{currencies}]",
|
||||
iterations=iterations,
|
||||
assets=", ".join(assets),
|
||||
currencies=", ".join(currencies),
|
||||
)
|
||||
self.irc.sendmsg(f"Slow ad update completed with {iterations} iterations: [{', '.join(assets)}] | [{', '.join(currencies)}]")
|
||||
|
||||
def autoprice(self, ads, currency):
|
||||
"""
|
||||
|
@ -858,3 +870,11 @@ class Agora(object):
|
|||
rtrn2 = self.agora.wallet_send_xmr(**send_cast)
|
||||
|
||||
self.irc.sendmsg(f"Withdrawal: {rtrn1['success']} | {rtrn2['success']}")
|
||||
self.notify.notify_withdrawal(profit_usd / 2)
|
||||
|
||||
def to_usd(self, amount, currency):
|
||||
if currency == "USD":
|
||||
return float(amount)
|
||||
else:
|
||||
rates = self.get_rates_all()
|
||||
return float(amount) / rates[currency]
|
||||
|
|
|
@ -15,6 +15,7 @@ from revolut import Revolut
|
|||
from agora import Agora
|
||||
from transactions import Transactions
|
||||
from irc import bot
|
||||
from notify import Notify
|
||||
|
||||
|
||||
def convert(data):
|
||||
|
@ -54,10 +55,20 @@ class WebApp(object):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Define Notify
|
||||
notify = Notify()
|
||||
|
||||
# Define IRC and Agora
|
||||
irc = bot()
|
||||
agora = Agora()
|
||||
|
||||
# Pass Notify to IRC and Agora
|
||||
irc.set_notify(notify)
|
||||
agora.set_notify(notify)
|
||||
|
||||
# Pass Agora to Notify
|
||||
notify.set_agora(agora)
|
||||
|
||||
# Pass IRC to Agora and Agora to IRC
|
||||
# This is to prevent recursive dependencies
|
||||
agora.set_irc(irc)
|
||||
|
@ -73,6 +84,9 @@ if __name__ == "__main__":
|
|||
# Define Transactions
|
||||
tx = Transactions()
|
||||
|
||||
# Pass Notify to Transactions
|
||||
tx.set_notify(notify)
|
||||
|
||||
# Pass Agora and IRC to Transactions and Transactions to IRC
|
||||
tx.set_agora(agora)
|
||||
tx.set_irc(irc)
|
||||
|
|
|
@ -12,7 +12,7 @@ class IRCCommands(object):
|
|||
helptext = "Get all open trades."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
"""
|
||||
Get details of open trades and post on IRC.
|
||||
"""
|
||||
|
@ -32,7 +32,7 @@ class IRCCommands(object):
|
|||
helptext = "Create an ad. Usage: create <XMR/BTC> <country> <currency>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
"""
|
||||
Post an ad on AgoraDesk with the given country and currency code.
|
||||
"""
|
||||
|
@ -52,7 +52,7 @@ class IRCCommands(object):
|
|||
helptext = "Get messages. Usage: messages [<reference>]"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
"""
|
||||
Get all messages for all open trades or a given trade.
|
||||
"""
|
||||
|
@ -86,7 +86,7 @@ class IRCCommands(object):
|
|||
helptext = "Distribute all our chosen currency and country ad pairs."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
# Distribute out our ad to all countries in the config
|
||||
for x in agora.dist_countries():
|
||||
if x["success"]:
|
||||
|
@ -100,7 +100,7 @@ class IRCCommands(object):
|
|||
# helptext = "Use a bruteforce algorithm to create all possible currency and country pairs."
|
||||
#
|
||||
# @staticmethod
|
||||
# def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
# def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
# for x in agora.dist_bruteforce():
|
||||
# if x["success"]:
|
||||
# msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
|
||||
|
@ -113,7 +113,7 @@ class IRCCommands(object):
|
|||
# helptext = "Resume a run of brute by getting all our adverts then filling the blanks."
|
||||
#
|
||||
# @staticmethod
|
||||
# def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
# def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
# for x in agora.bruteforce_fill_blanks():
|
||||
# if x["success"]:
|
||||
# msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
|
||||
|
@ -126,7 +126,7 @@ class IRCCommands(object):
|
|||
helptext = "Remove all duplicate adverts."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
rtrn = agora.strip_duplicate_ads()
|
||||
msg(dumps(rtrn))
|
||||
|
||||
|
@ -136,7 +136,7 @@ class IRCCommands(object):
|
|||
helptext = "Find a transaction. Usage: find <currency> <amount>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
"""
|
||||
Find a transaction received by Revolut with the given reference and amount.
|
||||
"""
|
||||
|
@ -158,7 +158,7 @@ class IRCCommands(object):
|
|||
helptext = "Get all account information from Revolut."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
accounts = revolut.accounts()
|
||||
accounts_posted = 0
|
||||
if accounts is None:
|
||||
|
@ -180,7 +180,7 @@ class IRCCommands(object):
|
|||
helptext = "Get total account balance from Revolut in USD."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
total_usd = revolut.get_total_usd()
|
||||
if total_usd is False:
|
||||
msg("Error getting total balance.")
|
||||
|
@ -192,7 +192,7 @@ class IRCCommands(object):
|
|||
helptext = "Get total account balance from Revolut and Agora."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
totals_all = tx.get_total()
|
||||
totals = totals_all[0]
|
||||
wallets = totals_all[1]
|
||||
|
@ -208,13 +208,22 @@ class IRCCommands(object):
|
|||
def run(cmd, spl, length, authed, msg):
|
||||
msg("Pong!")
|
||||
|
||||
class summon(object):
|
||||
name = "summon"
|
||||
authed = True
|
||||
helptext = "Summon all operators."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
notify.sendmsg("You have been summoned!")
|
||||
|
||||
class release_url(object):
|
||||
name = "release_url"
|
||||
authed = True
|
||||
helptext = "Get release URL for all open trades."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
trades = agora.dashboard_release_urls()
|
||||
if not trades:
|
||||
msg("No trades.")
|
||||
|
@ -227,7 +236,7 @@ class IRCCommands(object):
|
|||
helptext = "Send a message on a trade. Usage: msg <reference> <message...>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length > 2:
|
||||
full_msg = " ".join(spl[2:])
|
||||
reference = tx.ref_to_tx(spl[1])
|
||||
|
@ -243,7 +252,7 @@ class IRCCommands(object):
|
|||
helptext = "List all references"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
msg(f"References: {', '.join(tx.get_refs())}")
|
||||
|
||||
class ref(object):
|
||||
|
@ -252,7 +261,7 @@ class IRCCommands(object):
|
|||
helptext = "Get more information about a reference. Usage: ref <reference>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 2:
|
||||
ref_data = tx.get_ref(spl[1])
|
||||
if not ref_data:
|
||||
|
@ -266,7 +275,7 @@ class IRCCommands(object):
|
|||
helptext = "Delete a reference. Usage: del <reference>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 2:
|
||||
ref_data = tx.get_ref(spl[1])
|
||||
if not ref_data:
|
||||
|
@ -281,7 +290,7 @@ class IRCCommands(object):
|
|||
helptext = "Release funds for a trade. Usage: release <reference>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 2:
|
||||
tx = tx.ref_to_tx(spl[1])
|
||||
if not tx:
|
||||
|
@ -298,7 +307,7 @@ class IRCCommands(object):
|
|||
helptext = "Delete all our adverts."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
rtrn = agora.nuke_ads()
|
||||
msg(dumps(rtrn))
|
||||
|
||||
|
@ -308,7 +317,7 @@ class IRCCommands(object):
|
|||
helptext = "Get Agora wallet balances."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
rtrn_xmr = agora.agora.wallet_balance_xmr()
|
||||
if not rtrn_xmr["success"]:
|
||||
msg("Error getting XMR wallet details.")
|
||||
|
@ -328,7 +337,7 @@ class IRCCommands(object):
|
|||
helptext = "View public adverts. Usage: pubads <XMR/BTC> <currency>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 3:
|
||||
asset = spl[1]
|
||||
if asset not in loads(settings.Agora.AssetList):
|
||||
|
@ -345,7 +354,7 @@ class IRCCommands(object):
|
|||
helptext = "Cheat the markets by manipulating our prices to exploit people. Usage: cheat [<XMR/BTC>]"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 1:
|
||||
agora._update_prices()
|
||||
msg("Running cheat in thread.")
|
||||
|
@ -369,7 +378,7 @@ class IRCCommands(object):
|
|||
helptext = "Run the next currency for cheat."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 1:
|
||||
asset = agora._update_prices(None, None)
|
||||
msg(f"Running next asset for cheat in thread: {asset}")
|
||||
|
@ -380,7 +389,7 @@ class IRCCommands(object):
|
|||
helptext = "Get all our ad regions"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
ads = agora.enum_ads()
|
||||
for ad in ads:
|
||||
msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}")
|
||||
|
@ -391,7 +400,7 @@ class IRCCommands(object):
|
|||
helptext = "Get current XMR price."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
xmr_prices = agora.cg.get_price(ids="monero", vs_currencies=["sek", "usd", "gbp"])
|
||||
price_sek = xmr_prices["monero"]["sek"]
|
||||
price_usd = xmr_prices["monero"]["usd"]
|
||||
|
@ -404,7 +413,7 @@ class IRCCommands(object):
|
|||
helptext = "Get current BTC price."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
xmr_prices = agora.cg.get_price(ids="bitcoin", vs_currencies=["sek", "usd", "gbp"])
|
||||
price_sek = xmr_prices["bitcoin"]["sek"]
|
||||
price_usd = xmr_prices["bitcoin"]["usd"]
|
||||
|
@ -417,7 +426,7 @@ class IRCCommands(object):
|
|||
helptext = "Take profit."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
agora.withdraw_funds()
|
||||
|
||||
class shuffle(object):
|
||||
|
@ -426,7 +435,7 @@ class IRCCommands(object):
|
|||
helptext = "Convert all currencies in Revolut to supplied one. Usage: shuffle <currency>"
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx, notify):
|
||||
if length == 2:
|
||||
currency = spl[1]
|
||||
rtrn = revolut.shuffle(currency)
|
||||
|
|
|
@ -47,6 +47,9 @@ class IRCBot(irc.IRCClient):
|
|||
def set_tx(self, tx):
|
||||
self.tx = tx
|
||||
|
||||
def set_notify(self, notify):
|
||||
self.notify = notify
|
||||
|
||||
def parse(self, user, host, channel, msg):
|
||||
"""
|
||||
Simple handler for IRC commands.
|
||||
|
@ -97,7 +100,7 @@ class IRCBot(irc.IRCClient):
|
|||
# Check if the command required authentication
|
||||
if obj.authed:
|
||||
if host in self.admins:
|
||||
obj.run(cmd, spl, length, authed, msgl, self.agora, self.revolut, self.tx)
|
||||
obj.run(cmd, spl, length, authed, msgl, self.agora, self.revolut, self.tx, self.notify)
|
||||
else:
|
||||
# Handle authentication here instead of in the command module for security
|
||||
self.msg(channel, "Access denied.")
|
||||
|
@ -189,6 +192,9 @@ class IRCBotFactory(protocol.ClientFactory):
|
|||
def set_tx(self, tx):
|
||||
self.tx = tx
|
||||
|
||||
def set_notify(self, notify):
|
||||
self.notify = notify
|
||||
|
||||
def sendmsg(self, msg):
|
||||
"""
|
||||
Passthrough function to send a message to the channel.
|
||||
|
@ -210,6 +216,7 @@ class IRCBotFactory(protocol.ClientFactory):
|
|||
self.client.set_agora(self.agora)
|
||||
self.client.set_revolut(self.revolut)
|
||||
self.client.set_tx(self.tx)
|
||||
self.client.set_notify(self.notify)
|
||||
return prcol
|
||||
|
||||
def clientConnectionLost(self, connector, reason):
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# Twisted/Klein imports
|
||||
from twisted.logger import Logger
|
||||
|
||||
# Other library imports
|
||||
import requests
|
||||
|
||||
# Project imports
|
||||
from settings import settings
|
||||
|
||||
|
||||
class Notify(object):
|
||||
"""
|
||||
Class to handle more robust notifications.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.log = Logger("notify")
|
||||
|
||||
def set_agora(self, agora):
|
||||
self.agora = agora
|
||||
|
||||
def sendmsg(self, msg, title=None, priority=None, tags=None):
|
||||
headers = {"Title": "Bot"}
|
||||
if title:
|
||||
headers["Title"] = title
|
||||
if priority:
|
||||
headers["Priority"] = priority
|
||||
if tags:
|
||||
headers["Tags"] = tags
|
||||
requests.post(
|
||||
f"{settings.Notify.Host}/{settings.Notify.Topic}",
|
||||
data=msg,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
def notify_new_trade(self, amount, currency):
|
||||
amount_usd = self.agora.to_usd(amount, currency)
|
||||
self.sendmsg(f"Total: {amount_usd}", title="New trade", tags="trades")
|
||||
|
||||
def notify_complete_trade(self, amount, currency):
|
||||
amount_usd = self.agora.to_usd(amount, currency)
|
||||
self.sendmsg(f"Total: {amount_usd}", title="Trade complete", tags="trades,profit")
|
||||
|
||||
def notify_withdrawal(self, amount_usd):
|
||||
self.sendmsg(f"Total: {amount_usd}", title="Withdrawal", tags="profit")
|
|
@ -33,6 +33,9 @@ class Transactions(object):
|
|||
def set_revolut(self, revolut):
|
||||
self.revolut = revolut
|
||||
|
||||
def set_notify(self, notify):
|
||||
self.notify = notify
|
||||
|
||||
def transaction(self, data):
|
||||
"""
|
||||
Store details of transaction and post notifications to IRC.
|
||||
|
@ -232,6 +235,7 @@ class Transactions(object):
|
|||
|
||||
r.hmset(f"tx.{txid}", to_store)
|
||||
self.release_funds(stored_trade["id"], stored_trade["reference"])
|
||||
self.notify.notify_complete_trade(amount, currency)
|
||||
|
||||
def release_funds(self, trade_id, reference):
|
||||
self.log.info("All checks passed, releasing funds for {trade_id} {reference}", trade_id=trade_id, reference=reference)
|
||||
|
@ -266,6 +270,7 @@ class Transactions(object):
|
|||
self.log.info("Storing trade information: {info}", info=str(to_store))
|
||||
r.hmset(f"trade.{reference}", to_store)
|
||||
self.irc.sendmsg(f"Generated reference for {trade_id}: {reference}")
|
||||
self.notify.notify_new_trade(amount, currency)
|
||||
if settings.Agora.Send == "1":
|
||||
self.agora.agora.contact_message_post(trade_id, f"Hi! When sending the payment please use reference code: {reference}")
|
||||
if existing_ref:
|
||||
|
|
Loading…
Reference in New Issue