[tasks] Add auto tagging from titles
This commit is contained in:
@ -6,6 +6,7 @@ from django.utils import timezone
|
|||||||
|
|
||||||
from scrobbles.models import Scrobble
|
from scrobbles.models import Scrobble
|
||||||
from scrobbles.tasks import MEDIA_TYPES, update_charts_for_timestamp
|
from scrobbles.tasks import MEDIA_TYPES, update_charts_for_timestamp
|
||||||
|
from scrobbles.utils import tokenize_title_to_tags
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -48,3 +49,20 @@ def _update_charts_for_timestamp(user, ts):
|
|||||||
day = ts.day
|
day = ts.day
|
||||||
|
|
||||||
update_charts_for_timestamp.delay(user.id, year, month, day, week)
|
update_charts_for_timestamp.delay(user.id, year, month, day, week)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=Scrobble)
|
||||||
|
def add_tags_from_task_title(sender, instance, **kwargs):
|
||||||
|
if instance.media_type != Scrobble.MediaType.TASK:
|
||||||
|
return
|
||||||
|
|
||||||
|
title = instance.logdata.title
|
||||||
|
if not title:
|
||||||
|
return
|
||||||
|
|
||||||
|
new_tags = tokenize_title_to_tags(title)
|
||||||
|
existing_tags = {t.name for t in instance.tags.all()}
|
||||||
|
|
||||||
|
for tag in new_tags:
|
||||||
|
if tag not in existing_tags:
|
||||||
|
instance.tags.add(tag)
|
||||||
|
|||||||
@ -453,3 +453,64 @@ def next_url_if_exists(url: str) -> str:
|
|||||||
|
|
||||||
# If it doesn’t exist
|
# If it doesn’t exist
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
STOPWORDS = {
|
||||||
|
"a",
|
||||||
|
"an",
|
||||||
|
"the",
|
||||||
|
"and",
|
||||||
|
"or",
|
||||||
|
"but",
|
||||||
|
"in",
|
||||||
|
"on",
|
||||||
|
"at",
|
||||||
|
"to",
|
||||||
|
"for",
|
||||||
|
"of",
|
||||||
|
"with",
|
||||||
|
"by",
|
||||||
|
"from",
|
||||||
|
"is",
|
||||||
|
"as",
|
||||||
|
"it",
|
||||||
|
"be",
|
||||||
|
"are",
|
||||||
|
"was",
|
||||||
|
"were",
|
||||||
|
"been",
|
||||||
|
"have",
|
||||||
|
"has",
|
||||||
|
"had",
|
||||||
|
"do",
|
||||||
|
"does",
|
||||||
|
"did",
|
||||||
|
"will",
|
||||||
|
"would",
|
||||||
|
"could",
|
||||||
|
"should",
|
||||||
|
"might",
|
||||||
|
"must",
|
||||||
|
"this",
|
||||||
|
"that",
|
||||||
|
"these",
|
||||||
|
"those",
|
||||||
|
"your",
|
||||||
|
"their",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def tokenize_title_to_tags(title: str) -> list[str]:
|
||||||
|
"""Tokenize a title into tags, filtering common words and short tokens."""
|
||||||
|
if not title:
|
||||||
|
return []
|
||||||
|
|
||||||
|
cleaned = re.sub(r"[\(\)\[\]\{\}]", "", title)
|
||||||
|
cleaned = re.sub(r"[^\w\s]", "", cleaned)
|
||||||
|
|
||||||
|
words = [
|
||||||
|
w.lower()
|
||||||
|
for w in cleaned.split()
|
||||||
|
if w.lower() not in STOPWORDS and len(w) > 2
|
||||||
|
]
|
||||||
|
return words
|
||||||
|
|||||||
Reference in New Issue
Block a user