diff --git a/handler/agora.py b/handler/agora.py index 2afcc62..f4376f6 100644 --- a/handler/agora.py +++ b/handler/agora.py @@ -248,12 +248,12 @@ class Agora(object): if not ads["success"]: return False for ad in ads["response"]["data"]["ad_list"]: - ads_total.append([ad["data"]["ad_id"], ad["data"]["countrycode"], ad["data"]["currency"]]) + ads_total.append([ad["data"]["asset"], ad["data"]["ad_id"], ad["data"]["countrycode"], ad["data"]["currency"]]) if "pagination" in ads["response"]: if "next" in ads["response"]["pagination"]: page += 1 for ad in self.enum_ads(page): - ads_total.append([ad[0], ad[1], ad[2]]) + ads_total.append([ad[0], ad[1], ad[2], ad[3]]) return ads_total def last_online_recent(self, date): @@ -270,8 +270,12 @@ class Agora(object): self.log.debug("Seconds ago date for {date} ^ {now}: {x}", date=date, now=str(now), x=sec_ago_date) return sec_ago_date < 172800 - def enum_public_ads(self, currency, page=0): - ads = self.agora._api_call(api_method=f"buy-monero-online/{currency}/REVOLUT", query_values={"page": page}) + def enum_public_ads(self, coin, currency, page=0): + # buy-monero-online, buy-bitcoin-online + # Work around Agora weirdness calling it bitcoins + if coin == "bitcoin": + coin = "bitcoins" + ads = self.agora._api_call(api_method=f"buy-{coin}-online/{currency}/REVOLUT", query_values={"page": page}) if not ads["success"]: return False for ad in ads["response"]["data"]["ad_list"]: @@ -284,50 +288,69 @@ class Agora(object): if "pagination" in ads["response"]: if "next" in ads["response"]["pagination"]: page += 1 - for ad in self.enum_public_ads(currency, page): + for ad in self.enum_public_ads(coin, currency, page): yield [ad[0], ad[1], ad[2]] - def wrap_public_ads(self, currency, rates=None): + def wrap_public_ads(self, asset, currency, rates=None): """ Wrapper to sort public ads. """ - ads = list(self.enum_public_ads(currency.upper())) + if asset == "XMR": + coin = "monero" + elif asset == "BTC": + coin = "bitcoin" + ads = list(self.enum_public_ads(coin, currency.upper())) if not rates: - base_monero_price = self.cg.get_price(ids="monero", vs_currencies=currency)["monero"][currency.lower()] + # Set the price based on the asset + base_currency_price = self.cg.get_price(ids=coin, vs_currencies=currency)[coin][currency.lower()] else: - base_monero_price = rates + base_currency_price = rates for ad in ads: price = float(ad[2]) - rate = round(price / base_monero_price, 2) + rate = round(price / base_currency_price, 2) ad.append(rate) return ads - def _update_prices(self): + def _update_prices(self, xmr=True, btc=True): """ Update prices in another thread. """ - deferToThread(self.update_prices) + deferToThread(self.update_prices, xmr, btc) - def update_prices(self): + def update_prices(self, xmr=True, btc=True): our_ads = self.enum_ads() - currencies = [x[2].lower() for x in our_ads] - public_ad_dict = {} - rates_xmr = self.cg.get_price(ids="monero", vs_currencies=currencies) + currencies = [x[3].lower() for x in our_ads] + public_ad_dict_xmr = {} + public_ad_dict_btc = {} + rates_crypto = self.cg.get_price(ids=["monero", "bitcoin"], vs_currencies=currencies) for currency in currencies: try: - rates = rates_xmr["monero"][currency] - public_ad_dict[currency] = self.wrap_public_ads(currency, rates=rates) + rates_xmr = rates_crypto["monero"][currency] + rates_btc = rates_crypto["bitcoin"][currency] + if xmr: + public_ad_dict_xmr[currency] = self.wrap_public_ads("XMR", currency, rates=rates_xmr) + if btc: + public_ad_dict_btc[currency] = self.wrap_public_ads("BTC", currency, rates=rates_btc) except KeyError: self.log.error("Error getting public ads for currency {currency}", currency=currency) continue - for ad_id, country, currency in our_ads: + for asset, ad_id, country, currency in our_ads: # Get the ads for this country/currency pair try: - public_ads = public_ad_dict[currency.lower()] + if asset == "XMR": + public_ads = public_ad_dict_xmr[currency.lower()] + elif asset == "BTC": + public_ads = public_ad_dict_btc[currency.lower()] except KeyError: continue - new_margin = self.autoprice(public_ads, currency) - new_formula = f"coingeckoxmrusd*usd{currency.lower()}*{new_margin}" + if xmr: + if asset == "XMR": + new_margin = self.autoprice(public_ads, currency) + new_formula = f"coingeckoxmrusd*usd{currency.lower()}*{new_margin}" + if btc: + if asset == "BTC": + new_margin = self.autoprice(public_ads, currency) + new_formula = f"coingeckobtcusd*usd{currency.lower()}*{new_margin}" rtrn = self.agora.ad_equation(ad_id, new_formula) if not rtrn["success"]: self.log.error("Error updating ad {ad_id}: {response}", ad_id=ad_id, response=rtrn["response"]) @@ -520,11 +543,8 @@ class Agora(object): :rtype: bool or dict """ for asset in loads(settings.Agora.AssetList): - print("DIST ASSET", asset) for currency, countrycode in loads(settings.Agora.DistList): - print("DIST C/CC", currency, countrycode) rtrn = self.create_ad(asset, countrycode, currency) - print("RTRN", rtrn) if not rtrn: return False yield rtrn diff --git a/handler/commands.py b/handler/commands.py index 3c31c9d..9f3bc2b 100644 --- a/handler/commands.py +++ b/handler/commands.py @@ -4,6 +4,7 @@ from json import dumps, loads # Project imports from settings import settings + class IRCCommands(object): class trades(object): name = "trades" @@ -93,31 +94,31 @@ class IRCCommands(object): else: msg(dumps(x["response"])) -# 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" @@ -355,25 +356,43 @@ class IRCCommands(object): class pubads(object): name = "pubads" authed = True - helptext = "View public adverts. Usage: pubads " + helptext = "View public adverts. Usage: pubads " @staticmethod def run(cmd, spl, length, authed, msg, agora, revolut, tx): - if length == 2: - currency = spl[1] - rtrn = agora.wrap_public_ads(currency) + if length == 3: + asset = spl[1] + if asset not in loads(settings.Agora.AssetList): + msg(f"Not a valid asset: {spl[1]}") + return + currency = spl[2] + rtrn = agora.wrap_public_ads(asset, currency) for ad in rtrn: msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}") class cheat(object): name = "cheat" authed = True - helptext = "Cheat the markets by manipulating our prices to exploit people." + helptext = "Cheat the markets by manipulating our prices to exploit people. Usage: cheat []" @staticmethod def run(cmd, spl, length, authed, msg, agora, revolut, tx): - rtrn = agora._update_prices() - msg("Running cheat in thread.") + if length == 1: + agora._update_prices() + msg("Running cheat in thread.") + elif length == 2: + asset = spl[1] + if asset not in loads(settings.Agora.AssetList): + msg(f"Not a valid asset: {spl[1]}") + return + if asset == "XMR": + xmr = True + btc = False + elif asset == "BTC": + xmr = False + btc = True + agora._update_prices(xmr=xmr, btc=btc) + msg(f"Running cheat in thread for {asset}.") class ads(object): name = "ads" @@ -384,7 +403,7 @@ class IRCCommands(object): def run(cmd, spl, length, authed, msg, agora, revolut, tx): ads = agora.enum_ads() for ad in ads: - msg(f"({ad[0]}) {ad[1]} {ad[2]}") + msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}") class xmr(object): name = "xmr"