aboutsummaryrefslogtreecommitdiff
path: root/store.py
diff options
context:
space:
mode:
Diffstat (limited to 'store.py')
-rw-r--r--store.py72
1 files changed, 51 insertions, 21 deletions
diff --git a/store.py b/store.py
index 67e8a8f..467dd4b 100644
--- a/store.py
+++ b/store.py
@@ -3,7 +3,7 @@ import requests
3import portfolio 3import portfolio
4import simplejson as json 4import simplejson as json
5from decimal import Decimal as D, ROUND_DOWN 5from decimal import Decimal as D, ROUND_DOWN
6from datetime import date, datetime, timedelta 6import datetime
7import inspect 7import inspect
8from json import JSONDecodeError 8from json import JSONDecodeError
9from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError 9from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError
@@ -11,13 +11,16 @@ from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError
11__all__ = ["Portfolio", "BalanceStore", "ReportStore", "TradeStore"] 11__all__ = ["Portfolio", "BalanceStore", "ReportStore", "TradeStore"]
12 12
13class ReportStore: 13class ReportStore:
14 def __init__(self, market, verbose_print=True): 14 def __init__(self, market, verbose_print=True, no_http_dup=False):
15 self.market = market 15 self.market = market
16 self.verbose_print = verbose_print 16 self.verbose_print = verbose_print
17 17
18 self.print_logs = [] 18 self.print_logs = []
19 self.logs = [] 19 self.logs = []
20 20
21 self.no_http_dup = no_http_dup
22 self.last_http = None
23
21 def merge(self, other_report): 24 def merge(self, other_report):
22 self.logs += other_report.logs 25 self.logs += other_report.logs
23 self.logs.sort(key=lambda x: x["date"]) 26 self.logs.sort(key=lambda x: x["date"])
@@ -26,19 +29,26 @@ class ReportStore:
26 self.print_logs.sort(key=lambda x: x[0]) 29 self.print_logs.sort(key=lambda x: x[0])
27 30
28 def print_log(self, message): 31 def print_log(self, message):
29 now = datetime.now() 32 now = datetime.datetime.now()
30 message = "{:%Y-%m-%d %H:%M:%S}: {}".format(now, str(message)) 33 message = "{:%Y-%m-%d %H:%M:%S}: {}".format(now, str(message))
31 self.print_logs.append([now, message]) 34 self.print_logs.append([now, message])
32 if self.verbose_print: 35 if self.verbose_print:
33 print(message) 36 print(message)
34 37
35 def add_log(self, hash_): 38 def add_log(self, hash_):
36 hash_["date"] = datetime.now() 39 hash_["date"] = datetime.datetime.now()
40 if self.market is not None:
41 hash_["user_id"] = self.market.user_id
42 hash_["market_id"] = self.market.market_id
43 else:
44 hash_["user_id"] = None
45 hash_["market_id"] = None
37 self.logs.append(hash_) 46 self.logs.append(hash_)
47 return hash_
38 48
39 @staticmethod 49 @staticmethod
40 def default_json_serial(obj): 50 def default_json_serial(obj):
41 if isinstance(obj, (datetime, date)): 51 if isinstance(obj, (datetime.datetime, datetime.date)):
42 return obj.isoformat() 52 return obj.isoformat()
43 return str(obj) 53 return str(obj)
44 54
@@ -188,7 +198,12 @@ class ReportStore:
188 "error": response.__class__.__name__, 198 "error": response.__class__.__name__,
189 "error_message": str(response), 199 "error_message": str(response),
190 }) 200 })
191 else: 201 self.last_http = None
202 elif self.no_http_dup and \
203 self.last_http is not None and \
204 self.last_http["url"] == url and \
205 self.last_http["method"] == method and \
206 self.last_http["response"] == response.text:
192 self.add_log({ 207 self.add_log({
193 "type": "http_request", 208 "type": "http_request",
194 "method": method, 209 "method": method,
@@ -196,7 +211,19 @@ class ReportStore:
196 "body": body, 211 "body": body,
197 "headers": headers, 212 "headers": headers,
198 "status": response.status_code, 213 "status": response.status_code,
199 "response": response.text 214 "response": None,
215 "response_same_as": self.last_http["date"]
216 })
217 else:
218 self.last_http = self.add_log({
219 "type": "http_request",
220 "method": method,
221 "url": url,
222 "body": body,
223 "headers": headers,
224 "status": response.status_code,
225 "response": response.text,
226 "response_same_as": None,
200 }) 227 })
201 228
202 def log_error(self, action, message=None, exception=None): 229 def log_error(self, action, message=None, exception=None):
@@ -222,13 +249,11 @@ class ReportStore:
222 "action": action, 249 "action": action,
223 }) 250 })
224 251
225 def log_market(self, args, user_id, market_id): 252 def log_market(self, args):
226 self.add_log({ 253 self.add_log({
227 "type": "market", 254 "type": "market",
228 "commit": "$Format:%H$", 255 "commit": "$Format:%H$",
229 "args": vars(args), 256 "args": vars(args),
230 "user_id": user_id,
231 "market_id": market_id,
232 }) 257 })
233 258
234class BalanceStore: 259class BalanceStore:
@@ -382,7 +407,7 @@ class Portfolio:
382 data = LockedVar(None) 407 data = LockedVar(None)
383 liquidities = LockedVar({}) 408 liquidities = LockedVar({})
384 last_date = LockedVar(None) 409 last_date = LockedVar(None)
385 report = LockedVar(ReportStore(None)) 410 report = LockedVar(ReportStore(None, no_http_dup=True))
386 worker = None 411 worker = None
387 worker_started = False 412 worker_started = False
388 worker_notify = None 413 worker_notify = None
@@ -418,11 +443,17 @@ class Portfolio:
418 raise RuntimeError("This method needs to be ran with the worker") 443 raise RuntimeError("This method needs to be ran with the worker")
419 while cls.worker_started: 444 while cls.worker_started:
420 cls.worker_notify.wait() 445 cls.worker_notify.wait()
421 cls.worker_notify.clear() 446 if cls.worker_started:
422 cls.report.print_log("Fetching cryptoportfolio") 447 cls.worker_notify.clear()
423 cls.get_cryptoportfolio(refetch=True) 448 cls.report.print_log("Fetching cryptoportfolio")
424 cls.callback.set() 449 cls.get_cryptoportfolio(refetch=True)
425 time.sleep(poll) 450 cls.callback.set()
451 time.sleep(poll)
452
453 @classmethod
454 def stop_worker(cls):
455 cls.worker_started = False
456 cls.worker_notify.set()
426 457
427 @classmethod 458 @classmethod
428 def notify_and_wait(cls): 459 def notify_and_wait(cls):
@@ -433,7 +464,7 @@ class Portfolio:
433 @classmethod 464 @classmethod
434 def wait_for_recent(cls, delta=4, poll=30): 465 def wait_for_recent(cls, delta=4, poll=30):
435 cls.get_cryptoportfolio() 466 cls.get_cryptoportfolio()
436 while cls.last_date.get() is None or datetime.now() - cls.last_date.get() > timedelta(delta): 467 while cls.last_date.get() is None or datetime.datetime.now() - cls.last_date.get() > datetime.timedelta(delta):
437 if cls.worker is None: 468 if cls.worker is None:
438 time.sleep(poll) 469 time.sleep(poll)
439 cls.report.print_log("Attempt to fetch up-to-date cryptoportfolio") 470 cls.report.print_log("Attempt to fetch up-to-date cryptoportfolio")
@@ -490,7 +521,7 @@ class Portfolio:
490 weights_hash = portfolio_hash["weights"] 521 weights_hash = portfolio_hash["weights"]
491 weights = {} 522 weights = {}
492 for i in range(len(weights_hash["_row"])): 523 for i in range(len(weights_hash["_row"])):
493 date = datetime.strptime(weights_hash["_row"][i], "%Y-%m-%d") 524 date = datetime.datetime.strptime(weights_hash["_row"][i], "%Y-%m-%d")
494 weights[date] = dict(filter( 525 weights[date] = dict(filter(
495 filter_weights, 526 filter_weights,
496 map(clean_weights(i), weights_hash.items()))) 527 map(clean_weights(i), weights_hash.items())))
@@ -504,8 +535,7 @@ class Portfolio:
504 "high": high_liquidity, 535 "high": high_liquidity,
505 }) 536 })
506 cls.last_date.set(max( 537 cls.last_date.set(max(
507 max(medium_liquidity.keys(), default=datetime(1, 1, 1)), 538 max(medium_liquidity.keys(), default=datetime.datetime(1, 1, 1)),
508 max(high_liquidity.keys(), default=datetime(1, 1, 1)) 539 max(high_liquidity.keys(), default=datetime.datetime(1, 1, 1))
509 )) 540 ))
510 541
511