|
|
@ -7,42 +7,16 @@ from twisted.internet.threads import deferToThread
|
|
|
|
from json import loads
|
|
|
|
from json import loads
|
|
|
|
from forex_python.converter import CurrencyRates
|
|
|
|
from forex_python.converter import CurrencyRates
|
|
|
|
from agoradesk_py import AgoraDesk
|
|
|
|
from agoradesk_py import AgoraDesk
|
|
|
|
from httpx import ReadTimeout, ReadError, RemoteProtocolError
|
|
|
|
from pycoingecko import CoinGeckoAPI # TODO: remove this import and defer to money
|
|
|
|
from pycoingecko import CoinGeckoAPI
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from time import sleep
|
|
|
|
from time import sleep
|
|
|
|
from pyotp import TOTP
|
|
|
|
from pyotp import TOTP
|
|
|
|
|
|
|
|
|
|
|
|
# Project imports
|
|
|
|
# Project imports
|
|
|
|
from settings import settings
|
|
|
|
from settings import settings
|
|
|
|
|
|
|
|
import util
|
|
|
|
|
|
|
|
|
|
|
|
log = Logger("agora.global")
|
|
|
|
log = Logger("agora.global")
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: move to utils
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_exceptions(func):
|
|
|
|
|
|
|
|
def inner_function(*args, **kwargs):
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
rtrn = func(*args, **kwargs)
|
|
|
|
|
|
|
|
except (ReadTimeout, ReadError, RemoteProtocolError):
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
if isinstance(rtrn, dict):
|
|
|
|
|
|
|
|
if "success" in rtrn:
|
|
|
|
|
|
|
|
if "message" in rtrn:
|
|
|
|
|
|
|
|
if not rtrn["success"] and rtrn["message"] == "API ERROR":
|
|
|
|
|
|
|
|
if "error_code" in rtrn["response"]["error"]:
|
|
|
|
|
|
|
|
code = rtrn["response"]["error"]["error_code"]
|
|
|
|
|
|
|
|
if not code == 136:
|
|
|
|
|
|
|
|
log.error("API error: {code}", code=code)
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
log.error("API error: {code}", code=rtrn["response"]["error"])
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
return rtrn
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inner_function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Agora(object):
|
|
|
|
class Agora(object):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
@ -56,8 +30,8 @@ class Agora(object):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
self.log = Logger("agora")
|
|
|
|
self.log = Logger("agora")
|
|
|
|
self.agora = AgoraDesk(settings.Agora.Token)
|
|
|
|
self.agora = AgoraDesk(settings.Agora.Token)
|
|
|
|
self.cr = CurrencyRates()
|
|
|
|
self.cr = CurrencyRates() # TODO: remove this and defer to money
|
|
|
|
self.cg = CoinGeckoAPI()
|
|
|
|
self.cg = CoinGeckoAPI() # TODO: remove this and defer to money
|
|
|
|
|
|
|
|
|
|
|
|
# Cache for detecting new trades
|
|
|
|
# Cache for detecting new trades
|
|
|
|
self.last_dash = set()
|
|
|
|
self.last_dash = set()
|
|
|
@ -78,7 +52,7 @@ class Agora(object):
|
|
|
|
self.lc_cheat = LoopingCall(self.run_cheat_in_thread)
|
|
|
|
self.lc_cheat = LoopingCall(self.run_cheat_in_thread)
|
|
|
|
self.lc_cheat.start(int(settings.Agora.CheatSec))
|
|
|
|
self.lc_cheat.start(int(settings.Agora.CheatSec))
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def wrap_dashboard(self):
|
|
|
|
def wrap_dashboard(self):
|
|
|
|
dash = self.agora.dashboard_seller()
|
|
|
|
dash = self.agora.dashboard_seller()
|
|
|
|
if dash is None:
|
|
|
|
if dash is None:
|
|
|
@ -179,7 +153,7 @@ class Agora(object):
|
|
|
|
current_trades.append(reference)
|
|
|
|
current_trades.append(reference)
|
|
|
|
self.tx.cleanup(current_trades)
|
|
|
|
self.tx.cleanup(current_trades)
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def get_recent_messages(self, send_irc=True):
|
|
|
|
def get_recent_messages(self, send_irc=True):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Get recent messages.
|
|
|
|
Get recent messages.
|
|
|
@ -226,7 +200,7 @@ class Agora(object):
|
|
|
|
|
|
|
|
|
|
|
|
return messages_tmp
|
|
|
|
return messages_tmp
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def enum_ad_ids(self, page=0):
|
|
|
|
def enum_ad_ids(self, page=0):
|
|
|
|
ads = self.agora._api_call(api_method="ads", query_values={"page": page})
|
|
|
|
ads = self.agora._api_call(api_method="ads", query_values={"page": page})
|
|
|
|
if ads is False:
|
|
|
|
if ads is False:
|
|
|
@ -248,7 +222,7 @@ class Agora(object):
|
|
|
|
ads_total.append(ad)
|
|
|
|
ads_total.append(ad)
|
|
|
|
return ads_total
|
|
|
|
return ads_total
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def enum_ads(self, requested_asset=None, page=0):
|
|
|
|
def enum_ads(self, requested_asset=None, page=0):
|
|
|
|
query_values = {"page": page}
|
|
|
|
query_values = {"page": page}
|
|
|
|
if requested_asset:
|
|
|
|
if requested_asset:
|
|
|
@ -278,22 +252,7 @@ class Agora(object):
|
|
|
|
ads_total.append([ad[0], ad[1], ad[2], ad[3], ad[4]])
|
|
|
|
ads_total.append([ad[0], ad[1], ad[2], ad[3], ad[4]])
|
|
|
|
return ads_total
|
|
|
|
return ads_total
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: move to utils library
|
|
|
|
@util.handle_exceptions
|
|
|
|
def last_online_recent(self, date):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Check if the last online date was recent.
|
|
|
|
|
|
|
|
:param date: date last online
|
|
|
|
|
|
|
|
:type date: string
|
|
|
|
|
|
|
|
:return: bool indicating whether the date was recent enough
|
|
|
|
|
|
|
|
:rtype: bool
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
date_parsed = datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%fZ")
|
|
|
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
|
|
|
sec_ago_date = (now - date_parsed).total_seconds()
|
|
|
|
|
|
|
|
# self.log.debug("Seconds ago date for {date} ^ {now}: {x}", date=date, now=str(now), x=sec_ago_date)
|
|
|
|
|
|
|
|
return sec_ago_date < 172800
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
|
|
|
|
def enum_public_ads(self, asset, currency, providers=None, page=0):
|
|
|
|
def enum_public_ads(self, asset, currency, providers=None, page=0):
|
|
|
|
to_return = []
|
|
|
|
to_return = []
|
|
|
|
|
|
|
|
|
|
|
@ -326,7 +285,7 @@ class Agora(object):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
date_last_seen = ad["data"]["profile"]["last_online"]
|
|
|
|
date_last_seen = ad["data"]["profile"]["last_online"]
|
|
|
|
# Check if this person was seen recently
|
|
|
|
# Check if this person was seen recently
|
|
|
|
if not self.last_online_recent(date_last_seen):
|
|
|
|
if not util.last_online_recent(date_last_seen):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
ad_id = ad["data"]["ad_id"]
|
|
|
|
ad_id = ad["data"]["ad_id"]
|
|
|
|
username = ad["data"]["profile"]["username"]
|
|
|
|
username = ad["data"]["profile"]["username"]
|
|
|
@ -391,7 +350,7 @@ class Agora(object):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
deferToThread(self.update_prices, assets)
|
|
|
|
deferToThread(self.update_prices, assets)
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def update_prices(self, assets=None):
|
|
|
|
def update_prices(self, assets=None):
|
|
|
|
# Get all public ads for the given assets
|
|
|
|
# Get all public ads for the given assets
|
|
|
|
public_ads = self.get_all_public_ads(assets)
|
|
|
|
public_ads = self.get_all_public_ads(assets)
|
|
|
@ -403,7 +362,7 @@ class Agora(object):
|
|
|
|
self.slow_ad_update(to_update)
|
|
|
|
self.slow_ad_update(to_update)
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: make generic and move to markets
|
|
|
|
# TODO: make generic and move to markets
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def get_all_public_ads(self, assets=None, currencies=None, providers=None):
|
|
|
|
def get_all_public_ads(self, assets=None, currencies=None, providers=None):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Get all public ads for our listed currencies.
|
|
|
|
Get all public ads for our listed currencies.
|
|
|
@ -487,7 +446,7 @@ class Agora(object):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
iterations += 1
|
|
|
|
iterations += 1
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def nuke_ads(self):
|
|
|
|
def nuke_ads(self):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Delete all of our adverts.
|
|
|
|
Delete all of our adverts.
|
|
|
@ -534,7 +493,7 @@ class Agora(object):
|
|
|
|
max_local = max_usd * rates[currency]
|
|
|
|
max_local = max_usd * rates[currency]
|
|
|
|
return (min_local, max_local)
|
|
|
|
return (min_local, max_local)
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def create_ad(self, asset, countrycode, currency, provider, edit=False, ad_id=None):
|
|
|
|
def create_ad(self, asset, countrycode, currency, provider, edit=False, ad_id=None):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Post an ad with the given asset in a country with a given currency.
|
|
|
|
Post an ad with the given asset in a country with a given currency.
|
|
|
@ -654,7 +613,7 @@ class Agora(object):
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
yield (rtrn, ad_id)
|
|
|
|
yield (rtrn, ad_id)
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def strip_duplicate_ads(self):
|
|
|
|
def strip_duplicate_ads(self):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Remove duplicate ads.
|
|
|
|
Remove duplicate ads.
|
|
|
@ -676,7 +635,7 @@ class Agora(object):
|
|
|
|
actioned.append(rtrn["success"])
|
|
|
|
actioned.append(rtrn["success"])
|
|
|
|
return all(actioned)
|
|
|
|
return all(actioned)
|
|
|
|
|
|
|
|
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def release_funds(self, contact_id):
|
|
|
|
def release_funds(self, contact_id):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Release funds for a contact_id.
|
|
|
|
Release funds for a contact_id.
|
|
|
@ -695,7 +654,7 @@ class Agora(object):
|
|
|
|
return rtrn
|
|
|
|
return rtrn
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: write test before re-enabling adding total_trades
|
|
|
|
# TODO: write test before re-enabling adding total_trades
|
|
|
|
@handle_exceptions
|
|
|
|
@util.handle_exceptions
|
|
|
|
def withdraw_funds(self):
|
|
|
|
def withdraw_funds(self):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Withdraw excess funds to our XMR wallets.
|
|
|
|
Withdraw excess funds to our XMR wallets.
|
|
|
|