Libraries refactor and add some sinks #4
125
handler/agora.py
125
handler/agora.py
|
@ -95,16 +95,15 @@ class Agora(object):
|
|||
reference = self.tx.tx_to_ref(contact_id)
|
||||
buyer = contact["data"]["buyer"]["username"]
|
||||
amount = contact["data"]["amount"]
|
||||
if "amount_xmr" in contact["data"]:
|
||||
asset = contact["data"]["advertisement"]["asset"]
|
||||
if asset == "XMR":
|
||||
amount_crypto = contact["data"]["amount_xmr"]
|
||||
crypto = "XMR"
|
||||
elif "amount_btc" in contact["data"]:
|
||||
elif asset == "BTC":
|
||||
amount_crypto = contact["data"]["amount_btc"]
|
||||
crypto = "BTC"
|
||||
currency = contact["data"]["currency"]
|
||||
if not contact["data"]["is_selling"]:
|
||||
continue
|
||||
rtrn.append(f"{reference}: {buyer} {amount}{currency} {amount_crypto}{crypto}")
|
||||
rtrn.append(f"{reference}: {buyer} {amount}{currency} {amount_crypto}{asset}")
|
||||
return rtrn
|
||||
|
||||
def dashboard_hook(self, dash):
|
||||
|
@ -123,22 +122,21 @@ class Agora(object):
|
|||
current_trades.append(reference)
|
||||
buyer = contact["data"]["buyer"]["username"]
|
||||
amount = contact["data"]["amount"]
|
||||
if "amount_xmr" in contact["data"]:
|
||||
asset = contact["data"]["advertisement"]["asset"]
|
||||
if asset == "XMR":
|
||||
amount_crypto = contact["data"]["amount_xmr"]
|
||||
crypto = "XMR"
|
||||
elif "amount_btc" in contact["data"]:
|
||||
elif asset == "BTC":
|
||||
amount_crypto = contact["data"]["amount_btc"]
|
||||
crypto = "BTC"
|
||||
currency = contact["data"]["currency"]
|
||||
if not contact["data"]["is_selling"]:
|
||||
continue
|
||||
if reference not in self.last_dash:
|
||||
reference = self.tx.new_trade(contact_id, buyer, currency, amount, amount_xmr)
|
||||
reference = self.tx.new_trade(asset, contact_id, buyer, currency, amount, amount_crypto)
|
||||
if reference:
|
||||
if reference not in current_trades:
|
||||
current_trades.append(reference)
|
||||
# Let us know there is a new trade
|
||||
self.irc.sendmsg(f"AUTO {reference}: {buyer} {amount}{currency} {amount_crypto}{crypto}")
|
||||
self.irc.sendmsg(f"AUTO {reference}: {buyer} {amount}{currency} {amount_crypto}{asset}")
|
||||
# Note that we have seen this reference
|
||||
self.last_dash.add(reference)
|
||||
|
||||
|
@ -167,12 +165,11 @@ class Agora(object):
|
|||
contact_id = contact["data"]["contact_id"]
|
||||
buyer = contact["data"]["buyer"]["username"]
|
||||
amount = contact["data"]["amount"]
|
||||
if "amount_xmr" in contact["data"]:
|
||||
asset = contact["data"]["advertisement"]["asset"]
|
||||
if asset == "XMR":
|
||||
amount_crypto = contact["data"]["amount_xmr"]
|
||||
crypto = "XMR"
|
||||
elif "amount_btc" in contact["data"]:
|
||||
elif asset == "BTC":
|
||||
amount_crypto = contact["data"]["amount_btc"]
|
||||
crypto = "BTC"
|
||||
currency = contact["data"]["currency"]
|
||||
release_url = contact["actions"]["release_url"]
|
||||
if not contact["data"]["is_selling"]:
|
||||
|
@ -180,7 +177,7 @@ class Agora(object):
|
|||
reference = self.tx.tx_to_ref(contact_id)
|
||||
if not reference:
|
||||
reference = "not_set"
|
||||
dash_tmp.append(f"{reference}: {buyer} {amount}{currency} {amount_crypto}{crypto} {release_url}")
|
||||
dash_tmp.append(f"{reference}: {buyer} {amount}{currency} {amount_crypto}{asset} {release_url}")
|
||||
|
||||
return dash_tmp
|
||||
|
||||
|
@ -443,10 +440,12 @@ class Agora(object):
|
|||
max_local = max_usd * rates[currency]
|
||||
return (min_local, max_local)
|
||||
|
||||
def create_ad(self, countrycode, currency):
|
||||
def create_ad(self, asset, countrycode, currency):
|
||||
"""
|
||||
Post an ad in a country with a given currency.
|
||||
Post an ad with the given asset in a country with a given currency.
|
||||
Convert the min and max amounts from settings to the given currency with CurrencyRates.
|
||||
:param asset: the crypto asset to list (XMR or BTC)
|
||||
:type asset: string
|
||||
:param countrycode: country code
|
||||
:param currency: currency code
|
||||
:type countrycode: string
|
||||
|
@ -463,6 +462,7 @@ class Agora(object):
|
|||
else:
|
||||
adtext = ad.replace("$PAYMENT$", settings.Agora.DefaultDetailsAd)
|
||||
paymentdetailstext = paymentdetails.replace("$PAYMENT$", settings.Agora.DefaultDetailsPayment)
|
||||
ad = ad.replace("$ASSET$", asset)
|
||||
rates = self.get_rates_all()
|
||||
if currency == "USD":
|
||||
min_amount = float(settings.Agora.MinUSD)
|
||||
|
@ -478,7 +478,7 @@ class Agora(object):
|
|||
country_code=countrycode,
|
||||
currency=currency,
|
||||
trade_type="ONLINE_SELL",
|
||||
asset="XMR",
|
||||
asset=asset,
|
||||
price_equation=price_formula,
|
||||
track_max_amount=False,
|
||||
require_trusted_by_advertiser=False,
|
||||
|
@ -500,52 +500,53 @@ class Agora(object):
|
|||
:return: False or dict with response
|
||||
:rtype: bool or dict
|
||||
"""
|
||||
for currency, countrycode in loads(settings.Agora.DistList):
|
||||
rtrn = self.create_ad(countrycode, currency)
|
||||
if not rtrn:
|
||||
return False
|
||||
yield rtrn
|
||||
|
||||
def get_combinations(self):
|
||||
"""
|
||||
Get all combinations of currencies and countries from the configuration.
|
||||
:return: list of [country, currency]
|
||||
:rtype: list
|
||||
"""
|
||||
currencies = loads(settings.Agora.BruteCurrencies)
|
||||
countries = loads(settings.Agora.BruteCountries)
|
||||
combinations = [[country, currency] for country in countries for currency in currencies]
|
||||
return combinations
|
||||
|
||||
def dist_bruteforce(self):
|
||||
"""
|
||||
Bruteforce all possible ads from the currencies and countries in the config.
|
||||
Does not exit on errors.
|
||||
:return: False or dict with response
|
||||
:rtype: bool or dict
|
||||
"""
|
||||
combinations = self.get_combinations()
|
||||
for country, currency in combinations:
|
||||
rtrn = self.create_ad(country, currency)
|
||||
if not rtrn:
|
||||
yield False
|
||||
yield rtrn
|
||||
|
||||
def bruteforce_fill_blanks(self):
|
||||
"""
|
||||
Get the ads that we want to configure but have not, and fill in the blanks.
|
||||
:return: False or dict with response
|
||||
:rtype: bool or dict
|
||||
"""
|
||||
existing_ads = self.enum_ads()
|
||||
combinations = self.get_combinations()
|
||||
for country, currency in combinations:
|
||||
if not [country, currency] in existing_ads:
|
||||
rtrn = self.create_ad(country, currency)
|
||||
for asset in loads(settings.Agora.AssetList):
|
||||
for currency, countrycode in loads(settings.Agora.DistList):
|
||||
rtrn = self.create_ad(asset, countrycode, currency)
|
||||
if not rtrn:
|
||||
yield False
|
||||
return False
|
||||
yield rtrn
|
||||
|
||||
# def get_combinations(self):
|
||||
# """
|
||||
# Get all combinations of currencies and countries from the configuration.
|
||||
# :return: list of [country, currency]
|
||||
# :rtype: list
|
||||
# """
|
||||
# currencies = loads(settings.Agora.BruteCurrencies)
|
||||
# countries = loads(settings.Agora.BruteCountries)
|
||||
# combinations = [[country, currency] for country in countries for currency in currencies]
|
||||
# return combinations
|
||||
|
||||
# def dist_bruteforce(self):
|
||||
# """
|
||||
# Bruteforce all possible ads from the currencies and countries in the config.
|
||||
# Does not exit on errors.
|
||||
# :return: False or dict with response
|
||||
# :rtype: bool or dict
|
||||
# """
|
||||
# combinations = self.get_combinations()
|
||||
# for country, currency in combinations:
|
||||
# rtrn = self.create_ad(country, currency)
|
||||
# if not rtrn:
|
||||
# yield False
|
||||
# yield rtrn
|
||||
#
|
||||
# def bruteforce_fill_blanks(self):
|
||||
# """
|
||||
# Get the ads that we want to configure but have not, and fill in the blanks.
|
||||
# :return: False or dict with response
|
||||
# :rtype: bool or dict
|
||||
# """
|
||||
# existing_ads = self.enum_ads()
|
||||
# combinations = self.get_combinations()
|
||||
# for country, currency in combinations:
|
||||
# if not [country, currency] in existing_ads:
|
||||
# rtrn = self.create_ad(country, currency)
|
||||
# if not rtrn:
|
||||
# yield False
|
||||
# yield rtrn
|
||||
|
||||
def strip_duplicate_ads(self):
|
||||
"""
|
||||
Remove duplicate ads.
|
||||
|
|
|
@ -33,11 +33,15 @@ class IRCCommands(object):
|
|||
"""
|
||||
Post an ad on AgoraDesk with the given country and currency code.
|
||||
"""
|
||||
posted = agora.create_ad(spl[1], spl[2])
|
||||
if posted["success"]:
|
||||
msg(f"{posted['response']['data']['message']}: {posted['response']['data']['ad_id']}")
|
||||
else:
|
||||
msg(dumps(posted["response"]))
|
||||
if length == 4:
|
||||
if spl[1] not in loads(settings.Agora.AssetList):
|
||||
msg(f"Not a valid asset: {spl[1]}")
|
||||
return
|
||||
posted = agora.create_ad(spl[1], spl[2], spl[3])
|
||||
if posted["success"]:
|
||||
msg(f"{posted['response']['data']['message']}: {posted['response']['data']['ad_id']}")
|
||||
else:
|
||||
msg(dumps(posted["response"]))
|
||||
|
||||
class messages(object):
|
||||
name = "messages"
|
||||
|
@ -87,31 +91,31 @@ class IRCCommands(object):
|
|||
else:
|
||||
msg(x["response"]["data"]["message"])
|
||||
|
||||
class brute(object):
|
||||
name = "brute"
|
||||
authed = True
|
||||
helptext = "Use a bruteforce algorithm to create all possible currency and country pairs."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
for x in agora.dist_bruteforce():
|
||||
if x["success"]:
|
||||
msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
|
||||
else:
|
||||
msg(dumps(x))
|
||||
|
||||
class fillblanks(object):
|
||||
name = "fillblanks"
|
||||
authed = True
|
||||
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):
|
||||
for x in agora.bruteforce_fill_blanks():
|
||||
if x["success"]:
|
||||
msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
|
||||
else:
|
||||
msg(dumps(x))
|
||||
# class brute(object):
|
||||
# name = "brute"
|
||||
# authed = True
|
||||
# helptext = "Use a bruteforce algorithm to create all possible currency and country pairs."
|
||||
#
|
||||
# @staticmethod
|
||||
# def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
# for x in agora.dist_bruteforce():
|
||||
# if x["success"]:
|
||||
# msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
|
||||
# else:
|
||||
# msg(dumps(x))
|
||||
#
|
||||
# class fillblanks(object):
|
||||
# name = "fillblanks"
|
||||
# authed = True
|
||||
# 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):
|
||||
# for x in agora.bruteforce_fill_blanks():
|
||||
# if x["success"]:
|
||||
# msg(f"{x['response']['data']['message']}: {x['response']['data']['ad_id']}")
|
||||
# else:
|
||||
# msg(dumps(x))
|
||||
|
||||
class stripdupes(object):
|
||||
name = "stripdupes"
|
||||
|
@ -190,16 +194,30 @@ class IRCCommands(object):
|
|||
if total_usd_revolut is False:
|
||||
msg("Error getting Revolut balance.")
|
||||
return
|
||||
agora_wallet = agora.agora.wallet_balance_xmr()
|
||||
if not agora_wallet["success"]:
|
||||
msg("Error getting Agora balance.")
|
||||
agora_wallet_xmr = agora.agora.wallet_balance_xmr()
|
||||
if not agora_wallet_xmr["success"]:
|
||||
msg("Error getting Agora XMR balance.")
|
||||
return
|
||||
total_xmr_agora = agora_wallet["response"]["data"]["total"]["balance"]
|
||||
agora_wallet_btc = agora.agora.wallet_balance_btc()
|
||||
if not agora_wallet_btc["success"]:
|
||||
msg("Error getting Agora BTC balance.")
|
||||
return
|
||||
total_xmr_agora = agora_wallet_xmr["response"]["data"]["total"]["balance"]
|
||||
total_btc_agora = agora_wallet_btc["response"]["data"]["total"]["balance"]
|
||||
# Get the XMR -> USD exchange rate
|
||||
xmr_usd = agora.cg.get_price(ids="monero", vs_currencies=["USD"])
|
||||
|
||||
# Get the BTC -> USD exchange rate
|
||||
btc_usd = agora.cg.get_price(ids="bitcoin", vs_currencies=["USD"])
|
||||
|
||||
# Convert the Agora XMR total to USD
|
||||
total_usd_agora = float(total_xmr_agora) * xmr_usd["monero"]["usd"]
|
||||
total_usd_agora_xmr = float(total_xmr_agora) * xmr_usd["monero"]["usd"]
|
||||
|
||||
# Convert the Agora BTC total to USD
|
||||
total_usd_agora_btc = float(total_btc_agora) * btc_usd["bitcoin"]["usd"]
|
||||
|
||||
# Add it all up
|
||||
total_usd_agora = total_usd_agora_xmr + total_usd_agora_btc
|
||||
total_usd = total_usd_agora + total_usd_revolut
|
||||
|
||||
# Convert the total USD price to GBP and SEK
|
||||
|
@ -315,16 +333,22 @@ class IRCCommands(object):
|
|||
class wallet(object):
|
||||
name = "wallet"
|
||||
authed = True
|
||||
helptext = "Get Agora wallet balance in XMR."
|
||||
helptext = "Get Agora wallet balances."
|
||||
|
||||
@staticmethod
|
||||
def run(cmd, spl, length, authed, msg, agora, revolut, tx):
|
||||
rtrn = agora.agora.wallet_balance_xmr()
|
||||
if not rtrn["success"]:
|
||||
msg("Error getting wallet details.")
|
||||
rtrn_xmr = agora.agora.wallet_balance_xmr()
|
||||
if not rtrn_xmr["success"]:
|
||||
msg("Error getting XMR wallet details.")
|
||||
return
|
||||
balance = rtrn["response"]["data"]["total"]["balance"]
|
||||
msg(f"Wallet balance: {balance}XMR")
|
||||
rtrn_btc = agora.agora.wallet_balance()
|
||||
if not rtrn_btc["success"]:
|
||||
msg("Error getting BTC wallet details.")
|
||||
return
|
||||
balance_xmr = rtrn_xmr["response"]["data"]["total"]["balance"]
|
||||
balance_btc = rtrn_btc["response"]["data"]["total"]["balance"]
|
||||
msg(f"XMR wallet balance: {balance_xmr}")
|
||||
msg(f"BTC wallet balance: {balance_btc}")
|
||||
|
||||
class pubads(object):
|
||||
name = "pubads"
|
||||
|
|
|
@ -183,22 +183,23 @@ class Transactions(object):
|
|||
message_long = rtrn["response"]["data"]["message"]
|
||||
self.irc.sendmsg(f"{message} - {message_long}")
|
||||
|
||||
def new_trade(self, trade_id, buyer, currency, amount, amount_xmr):
|
||||
def new_trade(self, asset, trade_id, buyer, currency, amount, amount_crypto):
|
||||
"""
|
||||
Called when we have a new trade in Agora.
|
||||
Store details in Redis, generate a reference and optionally let the customer know the reference.
|
||||
"""
|
||||
reference = "".join(choices(ascii_uppercase, k=5))
|
||||
reference = f"XMR-{reference}"
|
||||
reference = f"{asset}-{reference}"
|
||||
existing_ref = r.get(f"trade.{trade_id}.reference")
|
||||
if not existing_ref:
|
||||
r.set(f"trade.{trade_id}.reference", reference)
|
||||
to_store = {
|
||||
"id": trade_id,
|
||||
"asset": asset,
|
||||
"buyer": buyer,
|
||||
"currency": currency,
|
||||
"amount": amount,
|
||||
"amount_xmr": amount_xmr,
|
||||
"amount_crypto": amount_crypto,
|
||||
"reference": reference,
|
||||
}
|
||||
self.log.info("Storing trade information: {info}", info=str(to_store))
|
||||
|
|
Loading…
Reference in New Issue