diff --git a/django/background_task/management/commands/remove_completed.py b/django/background_task/management/commands/remove_completed.py index 923646d..fea2ff7 100644 --- a/django/background_task/management/commands/remove_completed.py +++ b/django/background_task/management/commands/remove_completed.py @@ -7,13 +7,17 @@ from background_task.models import CompletedTask logger = logging.getLogger('labelbase') +def _remove_completed_task(): + threshold = timezone.now() - timedelta(days=1) + deleted_count, _ = CompletedTask.objects.filter(locked_at__lte=threshold).delete() + return deleted_count + class Command(BaseCommand): help = "Remove completed tasks after 1 day." def handle(self, *args, **options): try: - threshold = timezone.now() - timedelta(days=1) - deleted_count, _ = CompletedTask.objects.filter(locked_at__lte=threshold).delete() + deleted_count = _remove_completed_task() self.stdout.write(self.style.SUCCESS(f"Deleted {deleted_count} completed tasks.")) except Exception as ex: logger.exception("Error occurred while deleting completed tasks") diff --git a/django/crontab.txt b/django/crontab.txt index a23678a..337084a 100644 --- a/django/crontab.txt +++ b/django/crontab.txt @@ -1,2 +1 @@ * * * * * /usr/sbin/logrotate /app/logrotate.conf -1 0 * * * /usr/local/bin/python /app/manage.py remove_completed diff --git a/django/finances/signals.py b/django/finances/signals.py index a77a6d8..40fdbe6 100644 --- a/django/finances/signals.py +++ b/django/finances/signals.py @@ -16,7 +16,5 @@ def perform_tasks_on_login(sender, user, request, **kwargs): check_all_outputs(user.id) if Label.objects.filter(labelbase__user_id=user.id).exists(): messages.info(request, "Sync in progress: We are checking your unspent transaction outputs now.") - - # Store nearest price information. HistoricalPrice.get_or_create_from_api(-1) diff --git a/django/finances/tasks.py b/django/finances/tasks.py index 54d8dbd..fb43e22 100644 --- a/django/finances/tasks.py +++ b/django/finances/tasks.py @@ -1,5 +1,8 @@ import logging from background_task import background +from background_task.management.commands.remove_completed import _remove_completed_task + + from labelbase.models import Label from finances.electrum import checkup_label @@ -18,7 +21,8 @@ def check_all_outputs(user_id, labelbase_id=None, loop=None): if label.type == "output": logger.debug("check_spent, label.id {}".format(label.id)) check_spent(label.id) - + # Cleanup + _remove_completed_task() @background(schedule={'run_at': 0}, remove_existing_tasks=True) def check_spent(label_id, loop=None): diff --git a/django/knowledge_base/forms.py b/django/knowledge_base/forms.py index dca7c43..625830e 100644 --- a/django/knowledge_base/forms.py +++ b/django/knowledge_base/forms.py @@ -2,4 +2,4 @@ from django import forms class JSONUploadForm(forms.Form): - json_file = forms.FileField() # in memory upload + json_file = forms.FileField(label="Knowledge Base, JSON file format") # in memory upload diff --git a/django/labellabor/settings.py b/django/labellabor/settings.py index 32d799e..f6ba798 100644 --- a/django/labellabor/settings.py +++ b/django/labellabor/settings.py @@ -110,6 +110,7 @@ INSTALLED_APPS = [ "connectrum", "knowledge_base", "hashtags", + "statusapp", ] @@ -146,6 +147,7 @@ TEMPLATES = [ "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "sekizai.context_processors.sekizai", + "statusapp.context_processors.latest_status_message", ], }, }, diff --git a/django/statusapp/__init__.py b/django/statusapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/statusapp/admin.py b/django/statusapp/admin.py new file mode 100644 index 0000000..3371607 --- /dev/null +++ b/django/statusapp/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from .models import StatusMessage + +class StatusMessageAdmin(admin.ModelAdmin): + list_display = ['message', 'created_at'] + search_fields = ['message'] + +admin.site.register(StatusMessage, StatusMessageAdmin) diff --git a/django/statusapp/apps.py b/django/statusapp/apps.py new file mode 100644 index 0000000..4318161 --- /dev/null +++ b/django/statusapp/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class StatusappConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'statusapp' diff --git a/django/statusapp/context_processors.py b/django/statusapp/context_processors.py new file mode 100644 index 0000000..5e27f7f --- /dev/null +++ b/django/statusapp/context_processors.py @@ -0,0 +1,8 @@ +from .models import StatusMessage + +def latest_status_message(request): + try: + latest_message = StatusMessage.objects.latest('created_at') + except StatusMessage.DoesNotExist: + latest_message = None + return {'latest_status_message': latest_message} diff --git a/django/statusapp/migrations/0001_initial.py b/django/statusapp/migrations/0001_initial.py new file mode 100644 index 0000000..37b8103 --- /dev/null +++ b/django/statusapp/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.24 on 2024-03-19 22:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='StatusMessage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('message', models.CharField(max_length=1000)), + ('color', models.CharField(max_length=20)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + ), + ] diff --git a/django/statusapp/migrations/__init__.py b/django/statusapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/statusapp/models.py b/django/statusapp/models.py new file mode 100644 index 0000000..dd8d69b --- /dev/null +++ b/django/statusapp/models.py @@ -0,0 +1,9 @@ +from django.db import models + +class StatusMessage(models.Model): + message = models.CharField(max_length=1000) + color = models.CharField(max_length=20) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.message diff --git a/django/statusapp/tests.py b/django/statusapp/tests.py new file mode 100644 index 0000000..86276ad --- /dev/null +++ b/django/statusapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + + diff --git a/django/statusapp/views.py b/django/statusapp/views.py new file mode 100644 index 0000000..2536b37 --- /dev/null +++ b/django/statusapp/views.py @@ -0,0 +1 @@ +from django.shortcuts import render diff --git a/django/templates/_base.html b/django/templates/_base.html index 45c65cd..8ed0fa6 100644 --- a/django/templates/_base.html +++ b/django/templates/_base.html @@ -15,7 +15,7 @@ {% block extra_media %}{% endblock %} - + - -
- - - -
-
- -
- -
-
@@ -53,69 +28,5 @@ Thank you for your support! {% addtoblock "js" %} - if (!window.btcpay) { - var script = document.createElement('script'); - script.src = "http://178.194.166.112:3003/modal/btcpay.js"; - document.getElementsByTagName('head')[0].append(script); - } - function handleFormSubmit(event) { - event.preventDefault(); - var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function() { - if (this.readyState == 4 && this.status == 200 && this.responseText) { - window.btcpay.appendInvoiceFrame(JSON.parse(this.responseText).invoiceId); - } - }; - xhttp.open('POST', event.target.getAttribute('action'), true); - xhttp.send(new FormData(event.target)); - } - document.querySelectorAll(".btcpay-form").forEach(function(el) { - if (!el.dataset.initialized) { - el.addEventListener('submit', handleFormSubmit); - el.dataset.initialized = true; - } - }); - - function handlePlusMinus(event) { - event.preventDefault(); - const root = event.target.closest('.btcpay-form'); - const el = root.querySelector('.btcpay-input-price'); - const step = parseInt(event.target.dataset.step) || 1; - const min = parseInt(event.target.dataset.min) || 1; - const max = parseInt(event.target.dataset.max); - const type = event.target.dataset.type; - const price = parseInt(el.value) || min; - if (type === '-') { - el.value = price - step < min ? min : price - step; - } else if (type === '+') { - el.value = price + step > max ? max : price + step; - } - } - document.querySelectorAll(".btcpay-form .plus-minus").forEach(function(el) { - if (!el.dataset.initialized) { - el.addEventListener('click', handlePlusMinus); - el.dataset.initialized = true; - } - }); - - function handlePriceInput(event) { - event.preventDefault(); - const root = event.target.closest('.btcpay-form'); - const price = parseInt(event.target.dataset.price); - if (isNaN(event.target.value)) root.querySelector('.btcpay-input-price').value = price; - const min = parseInt(event.target.getAttribute('min')) || 1; - const max = parseInt(event.target.getAttribute('max')); - if (event.target.value < min) { - event.target.value = min; - } else if (event.target.value > max) { - event.target.value = max; - } - } - document.querySelectorAll(".btcpay-form .btcpay-input-price").forEach(function(el) { - if (!el.dataset.initialized) { - el.addEventListener('input', handlePriceInput); - el.dataset.initialized = true; - } - }); {% endaddtoblock %} {% endblock %} diff --git a/django/templates/knowledge_base/import_json.html b/django/templates/knowledge_base/import_json.html index da90d1f..d2e5310 100644 --- a/django/templates/knowledge_base/import_json.html +++ b/django/templates/knowledge_base/import_json.html @@ -1,14 +1,31 @@ - - - - Upload JSON - - -

Upload JSON File

+{% extends "_base.html" %} +{% load sekizai_tags %} +{% load i18n %} +{% load bootstrap %} +{% block title %}Upload Knowledge Base{% endblock %} +{% block nav_home %}active{% endblock %} + +{% block content %} + +
+

Upload Knowledge Base (JSON file)

+
+
{% csrf_token %} - {{ form.as_p }} - + {{ form|bootstrap }} +
+
- - +

+ + + + +
+ +{% addtoblock "js" %} + + +{% endaddtoblock %} +{% endblock %}