mirror of
https://github.com/Labelbase/Labelbase.git
synced 2026-08-16 13:01:02 +02:00
.
This commit is contained in:
parent
fedbd8ab0b
commit
b9ef1818ae
18 changed files with 110 additions and 113 deletions
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
* * * * * /usr/sbin/logrotate /app/logrotate.conf
|
||||
1 0 * * * /usr/local/bin/python /app/manage.py remove_completed
|
||||
|
|
|
|||
|
|
@ -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, "<strong>Sync in progress:</strong> We are checking your unspent transaction outputs now.")
|
||||
|
||||
|
||||
# Store nearest price information.
|
||||
HistoricalPrice.get_or_create_from_api(-1)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
|||
0
django/statusapp/__init__.py
Normal file
0
django/statusapp/__init__.py
Normal file
8
django/statusapp/admin.py
Normal file
8
django/statusapp/admin.py
Normal file
|
|
@ -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)
|
||||
6
django/statusapp/apps.py
Normal file
6
django/statusapp/apps.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class StatusappConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'statusapp'
|
||||
8
django/statusapp/context_processors.py
Normal file
8
django/statusapp/context_processors.py
Normal file
|
|
@ -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}
|
||||
23
django/statusapp/migrations/0001_initial.py
Normal file
23
django/statusapp/migrations/0001_initial.py
Normal file
|
|
@ -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)),
|
||||
],
|
||||
),
|
||||
]
|
||||
0
django/statusapp/migrations/__init__.py
Normal file
0
django/statusapp/migrations/__init__.py
Normal file
9
django/statusapp/models.py
Normal file
9
django/statusapp/models.py
Normal file
|
|
@ -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
|
||||
3
django/statusapp/tests.py
Normal file
3
django/statusapp/tests.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
|
||||
1
django/statusapp/views.py
Normal file
1
django/statusapp/views.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from django.shortcuts import render
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<link href="{% static 'css/dataTables.bootstrap5.min.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'css/labelbase.css' %}" rel="stylesheet">
|
||||
{% block extra_media %}{% endblock %}
|
||||
|
||||
|
||||
<style media="screen">
|
||||
{% block css %}{% endblock %}
|
||||
{% render_block "css" %}
|
||||
|
|
@ -26,10 +26,12 @@
|
|||
<body>
|
||||
|
||||
<!-- v1 -->
|
||||
<div style="background: goldenrod;z-index: 999999;position: relative;" class="d-block px-3 py-1 text-center text-bold skippy">
|
||||
<a href="#" class="text-white text-decoration-none">Run your self-hosted Labelbase! <u>Learn more</u></a>
|
||||
</div>
|
||||
{% if latest_status_message %}
|
||||
|
||||
<div style="background: {{ latest_status_message.color }}; z-index: 999999;position: relative;" class="d-block px-3 py-1 text-center text-bold skippy">
|
||||
<a href="#" class="text-white text-decoration-none">{{ latest_status_message.message }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end v1 -->
|
||||
<!-- v2 --
|
||||
<div style="background: rgb(33, 37, 41);z-index: 999999;position: relative;/*! padding: 11px; */" class="d-block px-3 py-1 text-center text-bold skippy">
|
||||
|
|
@ -181,9 +183,11 @@
|
|||
<span>Community</span>
|
||||
</h6>
|
||||
|
||||
{% comment %}
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link" href="{% url "donate" %}"><span data-feather="heart" class="align-text-bottom"></span> Donate</a>
|
||||
<li>
|
||||
{% endcomment %}
|
||||
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link" href="https://labelbase.space/newsletter/"><span data-feather="mail" class="align-text-bottom"></span> Newsletter</a>
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
{% block content %}
|
||||
|
||||
<div class=" p-3 pb-md-4 mx-auto text-left">
|
||||
<h2 class="display-8 fw-normal">Support Labelbase: Make a Difference with Your Donation</h2>
|
||||
<h2 class="display-8 fw-normal">Support Labelbase: Make a difference with your donation</h2>
|
||||
<br>
|
||||
<p class="fs-5 text-muted">Every Contribution Helps Us Build a Better Bitcoin Labeling Experience</p>
|
||||
<p class="fs-5 text-muted">Every contribution helps us build a better Bitcoin labeling experience.</p>
|
||||
<p class="fs-5 text-muted">
|
||||
Choose the amount you'd like to donate to Labelbase.
|
||||
</p> <p class="fs-5 text-muted">
|
||||
|
|
@ -20,32 +20,7 @@ Your generosity ensures that our project continues to thrive and evolve, directl
|
|||
Thank you for your support!
|
||||
</p>
|
||||
|
||||
<style>
|
||||
{% addtoblock "css" %}
|
||||
|
||||
.btcpay-form { display: inline-flex; align-items: center; justify-content: center; } .btcpay-form--inline { flex-direction: row; } .btcpay-form--block { flex-direction: column; } .btcpay-form--inline .submit { margin-left: 15px; } .btcpay-form--block select { margin-bottom: 10px; } .btcpay-form .btcpay-custom-container{ text-align: center; }.btcpay-custom { display: flex; align-items: center; justify-content: center; } .btcpay-form .plus-minus { cursor:pointer; font-size:25px; line-height: 25px; background: #DFE0E1; height: 30px; width: 45px; border:none; border-radius: 60px; margin: auto 5px; display: inline-flex; justify-content: center; } .btcpay-form select { -moz-appearance: none; -webkit-appearance: none; appearance: none; color: currentColor; background: transparent; border:1px solid transparent; display: block; padding: 1px; margin-left: auto; margin-right: auto; font-size: 11px; cursor: pointer; } .btcpay-form select:hover { border-color: #ccc; } .btcpay-form option { color: #000; background: rgba(0,0,0,.1); } .btcpay-input-price { -moz-appearance: textfield; border: none; box-shadow: none; text-align: center; font-size: 25px; margin: auto; border-radius: 5px; line-height: 35px; background: #fff; }.btcpay-input-price::-webkit-outer-spin-button, .btcpay-input-price::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
||||
|
||||
{% endaddtoblock %}
|
||||
</style>
|
||||
|
||||
<form method="POST" action="http://178.194.166.112:3003/api/v1/invoices" class="btcpay-form btcpay-form--block">
|
||||
<input type="hidden" name="storeId" value="77qPp3s5bGFQMfuStNWuWXmdKfn4t4tSQpvucQ4UdzKx" />
|
||||
<input type="hidden" name="jsonResponse" value="true" />
|
||||
<input type="hidden" name="notifyEmail" value="labelbase.space@proton.me" />
|
||||
<div class="btcpay-custom-container">
|
||||
<div class="btcpay-custom">
|
||||
<input class="btcpay-input-price" type="number" name="price" min="1" max="210000" step="1" value="1" data-price="1" style="width:2em;" />
|
||||
</div>
|
||||
<select name="currency">
|
||||
<option value="USD" selected>USD</option>
|
||||
<option value="GBP">GBP</option>
|
||||
<option value="EUR">EUR</option>
|
||||
<option value="BTC">BTC</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="submit" name="submit" style="min-width:146px;min-height:40px;border-radius:4px;border-style:none;background-color:#0f3b21;cursor:pointer;" title="Pay with BTCPay Server, a Self-Hosted Bitcoin Payment Processor"><span style="color:#fff">Donate with</span>
|
||||
<img src="http://178.194.166.112:3003/img/paybutton/logo.svg" style="height:40px;display:inline-block;padding:5% 0 5% 5px;vertical-align:middle;">
|
||||
</button></form>
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,31 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Upload JSON</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Upload JSON File</h1>
|
||||
{% extends "_base.html" %}
|
||||
{% load sekizai_tags %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap %}
|
||||
{% block title %}Upload Knowledge Base{% endblock %}
|
||||
{% block nav_home %}active{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class=" p-3 pb-md-4 mx-auto text-left">
|
||||
<h2 class="display-8 fw-normal">Upload Knowledge Base (JSON file)</h2>
|
||||
<br>
|
||||
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">Upload and import</button>
|
||||
{{ form|bootstrap }}
|
||||
<br>
|
||||
<button type="submit" class="btn btn-primary ">Upload and import</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{% addtoblock "js" %}
|
||||
|
||||
|
||||
{% endaddtoblock %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue