[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.tasks import MEDIA_TYPES, update_charts_for_timestamp
|
||||
from scrobbles.utils import tokenize_title_to_tags
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -48,3 +49,20 @@ def _update_charts_for_timestamp(user, ts):
|
||||
day = ts.day
|
||||
|
||||
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
|
||||
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