Add metadata and tags fields to Statement model; enhance search results to include statements
Close #44
This commit is contained in:
parent
4974c30397
commit
6563260b34
5 changed files with 67 additions and 2 deletions
|
@ -26,7 +26,7 @@ class NummiQuerySet(models.QuerySet):
|
||||||
),
|
),
|
||||||
SearchQuery(search, search_type="websearch"),
|
SearchQuery(search, search_type="websearch"),
|
||||||
),
|
),
|
||||||
similarity=TrigramSimilarity("name", search),
|
similarity=TrigramSimilarity(self.main_field, search),
|
||||||
)
|
)
|
||||||
.filter(models.Q(rank__gte=0.1) | models.Q(similarity__gte=0.3))
|
.filter(models.Q(rank__gte=0.1) | models.Q(similarity__gte=0.3))
|
||||||
.order_by("-rank")
|
.order_by("-rank")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "main/base.html" %}
|
{% extends "main/base.html" %}
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
{% load main_extras account_extras transaction_extras %}
|
{% load main_extras account_extras transaction_extras statement_extras %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% translate "Search" %} – Nummi
|
{% translate "Search" %} – Nummi
|
||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
|
@ -21,6 +21,12 @@
|
||||||
<div class="split">{% account_table accounts search=True %}</div>
|
<div class="split">{% account_table accounts search=True %}</div>
|
||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if statements %}
|
||||||
|
<section>
|
||||||
|
<h3>{% translate "Statements" %}</h3>
|
||||||
|
{% statement_table statements %}
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
{% if categories %}
|
{% if categories %}
|
||||||
<section>
|
<section>
|
||||||
<h3>{% translate "Categories" %}</h3>
|
<h3>{% translate "Categories" %}</h3>
|
||||||
|
|
|
@ -25,6 +25,7 @@ class SearchView(LoginRequiredMixin, TemplateView):
|
||||||
context["search"] = self.kwargs["search"]
|
context["search"] = self.kwargs["search"]
|
||||||
context["transactions"] = _user.transaction_set.search(self.kwargs["search"])
|
context["transactions"] = _user.transaction_set.search(self.kwargs["search"])
|
||||||
context["accounts"] = _user.account_set.search(self.kwargs["search"])
|
context["accounts"] = _user.account_set.search(self.kwargs["search"])
|
||||||
|
context["statements"] = _user.statement_set.search(self.kwargs["search"])
|
||||||
context["categories"] = _user.category_set.search(self.kwargs["search"])
|
context["categories"] = _user.category_set.search(self.kwargs["search"])
|
||||||
context["invoices"] = _user.invoice_set.search(self.kwargs["search"])[:10]
|
context["invoices"] = _user.invoice_set.search(self.kwargs["search"])[:10]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 4.2.7 on 2025-01-05 17:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("statement", "0003_remove_statement_diff_remove_statement_sum"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="statement",
|
||||||
|
name="metadata",
|
||||||
|
field=models.TextField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="statement",
|
||||||
|
name="tags",
|
||||||
|
field=models.TextField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -7,7 +7,17 @@ from django.core.validators import FileExtensionValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from main.models import NummiQuerySet
|
||||||
|
from main.utils import pdf_outline_to_str
|
||||||
from media.utils import get_path
|
from media.utils import get_path
|
||||||
|
from pypdf import PdfReader
|
||||||
|
|
||||||
|
|
||||||
|
class StatementQuerySet(NummiQuerySet):
|
||||||
|
main_field = "metadata"
|
||||||
|
fields = {
|
||||||
|
"tags": "B",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Statement(AccountModel):
|
class Statement(AccountModel):
|
||||||
|
@ -30,6 +40,10 @@ class Statement(AccountModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
default="",
|
default="",
|
||||||
)
|
)
|
||||||
|
metadata = models.TextField(blank=True)
|
||||||
|
tags = models.TextField(blank=True)
|
||||||
|
|
||||||
|
objects = StatementQuerySet.as_manager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return _("%(date)s statement") % {"date": self.date}
|
return _("%(date)s statement") % {"date": self.date}
|
||||||
|
@ -40,6 +54,28 @@ class Statement(AccountModel):
|
||||||
if _prever.file and _prever.file != self.file:
|
if _prever.file and _prever.file != self.file:
|
||||||
Path(_prever.file.path).unlink(missing_ok=True)
|
Path(_prever.file.path).unlink(missing_ok=True)
|
||||||
|
|
||||||
|
if self.file:
|
||||||
|
reader = PdfReader(self.file)
|
||||||
|
|
||||||
|
if reader.metadata:
|
||||||
|
self.metadata = " ".join(
|
||||||
|
(
|
||||||
|
m.replace("\x00", "").strip()
|
||||||
|
for m in (
|
||||||
|
reader.metadata.title,
|
||||||
|
reader.metadata.author,
|
||||||
|
reader.metadata.subject,
|
||||||
|
)
|
||||||
|
if m
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
_tags = pdf_outline_to_str(reader.outline)
|
||||||
|
_tags += " ".join(
|
||||||
|
(page.extract_text().replace("\x00", "") for page in reader.pages)
|
||||||
|
)
|
||||||
|
self.tags = " ".join((tag for tag in _tags.split() if len(tag) >= 3))
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue