diff --git a/api/admin.py b/api/admin.py index 2b485053..8507a508 100644 --- a/api/admin.py +++ b/api/admin.py @@ -45,7 +45,8 @@ class UserProfileAdmin(AdminChangeLinksMixin, admin.ModelAdmin): @admin.register(Currency) class CurrencieAdmin(admin.ModelAdmin): - list_display = ('currency','exchange_rate','timestamp') + list_display = ('id','currency','exchange_rate','timestamp') + list_display_links = ('id','currency') readonly_fields = ('currency','exchange_rate','timestamp') @admin.register(MarketTick) diff --git a/api/logics.py b/api/logics.py index 1fd8105b..e31937f5 100644 --- a/api/logics.py +++ b/api/logics.py @@ -95,13 +95,23 @@ class Logics(): return price, premium - def order_expires(order): + @classmethod + def order_expires(cls, order): ''' General case when time runs out. Only used when the maker does not lock a publishing bond''' - order.status = Order.Status.EXP - order.maker = None - order.taker = None - order.save() + + if order.status == Order.Status.WFB: + order.status = Order.Status.EXP + order.maker = None + order.taker = None + order.save() + + if order.status == Order.Status.PUB: + cls.return_bond(order.maker_bond) + order.status = Order.Status.EXP + order.maker = None + order.taker = None + order.save() def kick_taker(order): ''' The taker did not lock the taker_bond. Now he has to go''' diff --git a/api/tasks.py b/api/tasks.py index fc6f65d2..2bd04398 100644 --- a/api/tasks.py +++ b/api/tasks.py @@ -11,6 +11,7 @@ from datetime import timedelta from django.utils import timezone from decouple import config +import time @shared_task(name="users_cleansing") def users_cleansing(): @@ -42,18 +43,51 @@ def users_cleansing(): @shared_task(name="orders_expire") -def orders_expire(): - pass +def orders_expire(rest_secs): + ''' + Continuously checks order expiration times for 1 hour. + If order is expires, it handles the actions. + ''' + now = timezone.now() + end_time = now + timedelta(hours=1) + context = [] + + while now < end_time: + queryset = Order.objects.exclude(status=Order.Status.EXP).exclude(status=Order.Status.UCA).exclude(status= Order.Status.CCA) + queryset = queryset.filter(expires_at__lt=now) # expires at lower than now + + for order in queryset: + context.append(str(order)+ " was "+ Order.Status(order.status).label) + Logics.order_expires(order) + + # Allow for some thread rest. + time.sleep(rest_secs) + + # Update 'now' for a new loop + now = timezone.now() + + results = { + 'num_expired': len(context), + 'expired_orders_context': context, + 'rest_param': rest_secs, + } + + return results @shared_task def follow_lnd_payment(): + ''' Makes a payment and follows it. + Updates the LNpayment object, and retries + until payment is done''' pass @shared_task -def query_all_lnd_invoices(): +def follow_lnd_hold_invoice(): + ''' Follows and updates LNpayment object + until settled or canceled''' pass -@shared_task(name="cache_market", ignore_result=True) +@shared_task(name="cache_external_market_prices", ignore_result=True) def cache_market(): exchange_rates = get_exchange_rates(list(Currency.currency_dict.values())) results = {} @@ -65,7 +99,7 @@ def cache_market(): Currency.objects.update_or_create( id = int(val), currency = int(val), - # if there is a Cached Exchange rate matching that value, it updates it with defaults below + # if there is a Cached market prices matching that id, it updates it with defaults below defaults = { 'exchange_rate': rate, 'timestamp': timezone.now(), diff --git a/frontend/src/components/MakerPage.js b/frontend/src/components/MakerPage.js index 7d2da795..61b967e9 100644 --- a/frontend/src/components/MakerPage.js +++ b/frontend/src/components/MakerPage.js @@ -2,6 +2,8 @@ import React, { Component } from 'react'; import { Paper, Alert, AlertTitle, Button , Grid, Typography, TextField, Select, FormHelperText, MenuItem, FormControl, Radio, FormControlLabel, RadioGroup, Menu} from "@mui/material" import { Link } from 'react-router-dom' +import getFlags from './getFlags' + function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { @@ -190,7 +192,9 @@ export default class MakerPage extends Component { > { Object.entries(this.state.currencies_dict) - .map( ([key, value]) => {value} ) + .map( ([key, value]) => + {getFlags(value) + " " + value} + ) } diff --git a/frontend/src/components/OrderPage.js b/frontend/src/components/OrderPage.js index 748be167..b5a26bf7 100644 --- a/frontend/src/components/OrderPage.js +++ b/frontend/src/components/OrderPage.js @@ -2,6 +2,7 @@ import React, { Component } from "react"; import { Alert, Paper, CircularProgress, Button , Grid, Typography, List, ListItem, ListItemIcon, ListItemText, ListItemAvatar, Avatar, Divider, Box, LinearProgress} from "@mui/material" import Countdown, { zeroPad, calcTimeDelta } from 'react-countdown'; import TradeBox from "./TradeBox"; +import getFlags from './getFlags' // icons import AccessTimeIcon from '@mui/icons-material/AccessTime'; @@ -281,9 +282,10 @@ export default class OrderPage extends Component { - + {getFlags(this.state.currencyCode)} - + diff --git a/robosats/celery/__init__.py b/robosats/celery/__init__.py index cba1b059..df462750 100644 --- a/robosats/celery/__init__.py +++ b/robosats/celery/__init__.py @@ -32,14 +32,18 @@ app.conf.beat_scheduler = 'django_celery_beat.schedulers:DatabaseScheduler' # Configure the periodic tasks app.conf.beat_schedule = { # User cleansing every 6 hours - 'users-cleansing': { + 'users-cleansing': { # Cleans abandoned users every 6 hours 'task': 'users_cleansing', - 'schedule': timedelta(hours=6), + 'schedule': timedelta(hours=6), }, - - 'cache-market-rates': { - 'task': 'cache_market', - 'schedule': timedelta(seconds=60), # Cache market prices every minutes for now. + 'cache-market-prices': { # Cache market prices every minutes for now. + 'task': 'cache_external_market_prices', + 'schedule': timedelta(seconds=60), + }, + 'orders_expire': { # Continuous order expire removal (1 hour long process, every hour reports results) + 'task': 'orders_expire', + 'schedule': timedelta(hours=1), + 'args': [5], # Rest between checks (secs) }, }