diff options
Diffstat (limited to 'store.py')
-rw-r--r-- | store.py | 72 |
1 files changed, 51 insertions, 21 deletions
@@ -3,7 +3,7 @@ import requests | |||
3 | import portfolio | 3 | import portfolio |
4 | import simplejson as json | 4 | import simplejson as json |
5 | from decimal import Decimal as D, ROUND_DOWN | 5 | from decimal import Decimal as D, ROUND_DOWN |
6 | from datetime import date, datetime, timedelta | 6 | import datetime |
7 | import inspect | 7 | import inspect |
8 | from json import JSONDecodeError | 8 | from json import JSONDecodeError |
9 | from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError | 9 | from 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 | ||
13 | class ReportStore: | 13 | class 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 | ||
234 | class BalanceStore: | 259 | class 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 | |||