[moods] Update moods to Apple wellness flow
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from moods.models import Mood
|
||||
from moods.models import Mood, MoodReason
|
||||
from scrobbles.admin import ScrobbleInline
|
||||
|
||||
|
||||
@ -15,9 +15,16 @@ class MoodAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"uuid",
|
||||
"title",
|
||||
"mood_type",
|
||||
)
|
||||
ordering = ("-created",)
|
||||
search_fields = ("title",)
|
||||
inlines = [
|
||||
ScrobbleInline,
|
||||
]
|
||||
|
||||
|
||||
@admin.register(MoodReason)
|
||||
class MoodReasonAdmin(admin.ModelAdmin):
|
||||
list_display = ("title", "uuid")
|
||||
search_fields = ("title",)
|
||||
|
||||
164
vrobbler/apps/moods/fixtures/mood_reasons.json
Normal file
164
vrobbler/apps/moods/fixtures/mood_reasons.json
Normal file
@ -0,0 +1,164 @@
|
||||
[
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"uuid": "efdfc694-1b1b-4623-b645-6c0749eb6acd",
|
||||
"title": "Community",
|
||||
"description": "Feelings related to community interactions and sense of belonging"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"uuid": "1f5f347f-d73e-4853-b4cd-6c346d3a9c98",
|
||||
"title": "Current Events",
|
||||
"description": "Feelings influenced by news, politics, or current world events"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"uuid": "8765cc40-8ce6-4d08-b4ee-4c50f27201b8",
|
||||
"title": "Dating",
|
||||
"description": "Feelings related to romantic dating experiences"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"uuid": "5844f70f-a971-469c-b886-4949da4dd581",
|
||||
"title": "Education",
|
||||
"description": "Feelings related to learning, school, or educational pursuits"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"uuid": "ead56adf-671f-44cd-a61f-98a7e553a57a",
|
||||
"title": "Family",
|
||||
"description": "Feelings related to family interactions and relationships"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"uuid": "2ca7a801-0933-43e3-967b-c1ee973ccf8d",
|
||||
"title": "Fitness",
|
||||
"description": "Feelings related to physical fitness, exercise, or workout experiences"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"uuid": "1d0fb8bf-dc1d-4fd0-b158-69a2b8683524",
|
||||
"title": "Friends",
|
||||
"description": "Feelings related to friendships and social interactions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 8,
|
||||
"fields": {
|
||||
"uuid": "6c6b50b5-b737-4cdb-b163-96c4ec8d674f",
|
||||
"title": "Health",
|
||||
"description": "Feelings related to physical or mental health"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 9,
|
||||
"fields": {
|
||||
"uuid": "2568d6db-80fc-4b5b-b4e2-8a7cd28b0a01",
|
||||
"title": "Hobbies",
|
||||
"description": "Feelings related to personal hobbies and leisure activities"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 10,
|
||||
"fields": {
|
||||
"uuid": "c1363eb0-16c6-4c98-8237-323f43b508b0",
|
||||
"title": "Identity",
|
||||
"description": "Feelings related to self-identity, gender, or personal identity exploration"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 11,
|
||||
"fields": {
|
||||
"uuid": "97f28eec-0354-46b7-9d8c-b45c3d12f83e",
|
||||
"title": "Money",
|
||||
"description": "Feelings related to financial situations, spending, or money matters"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 12,
|
||||
"fields": {
|
||||
"uuid": "653eb557-443f-4ab0-ae93-06007b12e747",
|
||||
"title": "Partner",
|
||||
"description": "Feelings related to romantic partner or significant other"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 13,
|
||||
"fields": {
|
||||
"uuid": "4a1cf35d-3b3e-4042-a2cf-8c0fa6160113",
|
||||
"title": "Self-Care",
|
||||
"description": "Feelings related to self-care practices and mental health maintenance"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 14,
|
||||
"fields": {
|
||||
"uuid": "fffcd937-187e-476a-99e3-8f13eef6abc9",
|
||||
"title": "Spirituality",
|
||||
"description": "Feelings related to spiritual beliefs, practices, or experiences"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 15,
|
||||
"fields": {
|
||||
"uuid": "29af8f56-bc32-43a0-8b37-c1878d453bff",
|
||||
"title": "Tasks",
|
||||
"description": "Feelings related to work tasks, chores, or to-do items"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 16,
|
||||
"fields": {
|
||||
"uuid": "3dafed9b-941b-4907-8dc2-5d8f16dd7ed1",
|
||||
"title": "Travel",
|
||||
"description": "Feelings related to travel experiences, trips, or vacations"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 17,
|
||||
"fields": {
|
||||
"uuid": "2e4a9da6-bef4-4a74-87eb-3d9a32bfadc1",
|
||||
"title": "Weather",
|
||||
"description": "Feelings influenced by weather conditions or climate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "moods.moodreason",
|
||||
"pk": 18,
|
||||
"fields": {
|
||||
"uuid": "78858fcb-0850-4973-9ead-df66818e2a76",
|
||||
"title": "Work",
|
||||
"description": "Feelings related to work, career, or professional life"
|
||||
}
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
46
vrobbler/apps/moods/migrations/0006_add_mood_type_to_mood.py
Normal file
46
vrobbler/apps/moods/migrations/0006_add_mood_type_to_mood.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Generated by Django 4.2.29 on 2026-04-28 18:03
|
||||
|
||||
from django.db import migrations, models
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("moods", "0005_mood_tags"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="MoodReason",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
blank=True, default=uuid.uuid4, editable=False, null=True
|
||||
),
|
||||
),
|
||||
("title", models.CharField(blank=True, max_length=255, null=True)),
|
||||
("description", models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="mood",
|
||||
name="mood_type",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[("positive", "Positive"), ("negative", "Negative")],
|
||||
max_length=20,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,104 @@
|
||||
# Generated by Django 4.2.29 on 2026-04-28 18:06
|
||||
|
||||
from django.db import migrations
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
def update_moods_to_apple_list(apps, schema_editor):
|
||||
Mood = apps.get_model("moods", "Mood")
|
||||
Scrobble = apps.get_model("scrobbles", "Scrobble")
|
||||
|
||||
# Mapping of old mood titles to new adverb titles with mood_type
|
||||
# Format: old_title -> (new_title, mood_type)
|
||||
mood_mapping = {
|
||||
"Anxious": ("Anxiously", "negative"),
|
||||
"Fear": ("Fear", "negative"),
|
||||
"Sadness": ("Sadly", "negative"),
|
||||
"Anger": ("Angrily", "negative"),
|
||||
"Surprise": ("Surprisingly", "positive"),
|
||||
"Disgust": ("Disgustedly", "negative"),
|
||||
"Joy": ("Joyfully", "positive"),
|
||||
"Admiration": ("Admiration", "positive"),
|
||||
"Adoration": ("Adoration", "positive"),
|
||||
"Aesthetic Appreciation": ("Aesthetic Appreciation", "positive"),
|
||||
"Amusement": ("Amusedly", "positive"),
|
||||
"Awe": ("Amazingly", "positive"),
|
||||
"Awkwardness": ("Awkwardness", "negative"),
|
||||
"Boredom": ("Boredom", "negative"),
|
||||
"Calmness": ("Calmly", "positive"),
|
||||
"Confusion": ("Confusion", "negative"),
|
||||
"Craving/Desire": ("Craving/Desire", "positive"),
|
||||
"Empathetic pain": ("Empathetic pain", "negative"),
|
||||
"Entrancement": ("Entrancement", "positive"),
|
||||
"Excitement": ("Excitedly", "positive"),
|
||||
"Horror": ("Horror", "negative"),
|
||||
"Interest": ("Interest", "positive"),
|
||||
"Nostalgia": ("Nostalgia", "positive"),
|
||||
"Relief": ("Relievedly", "positive"),
|
||||
"Romance": ("Romance", "positive"),
|
||||
"Satisfaction": ("Satisfiedly", "positive"),
|
||||
}
|
||||
|
||||
# Apple moods (adverbs) with their mood_type
|
||||
# Tier1 (positive)
|
||||
apple_positive = [
|
||||
"Amazingly", "Amusedly", "Bravely", "Calmly", "Confidently",
|
||||
"Contentedly", "Excitedly", "Gratefully", "Happily", "Hopefully",
|
||||
"Joyfully", "Passionately", "Peacefully", "Proudly", "Relievedly",
|
||||
"Satisfiedly", "Surprisingly",
|
||||
]
|
||||
# Tier2 (negative)
|
||||
apple_negative = [
|
||||
"Angrily", "Annoyedly", "Anxiously", "Ashamedly", "Disappointedly",
|
||||
"Discouragedly", "Disgustedly", "Drainedly", "Embarrassedly",
|
||||
"Frustratedly", "Guiltily", "Hopelessly", "Indifferently",
|
||||
"Irritatedly", "Jealously", "Lonelily", "Overwhelmingly", "Sadly",
|
||||
"Scaredly", "Stressedly", "Worriedly",
|
||||
]
|
||||
|
||||
apple_moods = set(apple_positive + apple_negative)
|
||||
|
||||
# Update existing moods
|
||||
for old_title, (new_title, mood_type) in mood_mapping.items():
|
||||
try:
|
||||
mood = Mood.objects.get(title=old_title)
|
||||
mood.title = new_title
|
||||
mood.mood_type = mood_type
|
||||
mood.save()
|
||||
except Mood.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Delete moods with no scrobbles that aren't in Apple list
|
||||
moods_to_check = Mood.objects.filter(mood_type__isnull=True)
|
||||
for mood in moods_to_check:
|
||||
if not Scrobble.objects.filter(mood=mood).exists():
|
||||
if mood.title not in apple_moods:
|
||||
mood.delete()
|
||||
|
||||
# Create missing Apple moods
|
||||
for title in apple_positive:
|
||||
Mood.objects.get_or_create(
|
||||
title=title,
|
||||
defaults={"mood_type": "positive", "uuid": uuid4()}
|
||||
)
|
||||
|
||||
for title in apple_negative:
|
||||
Mood.objects.get_or_create(
|
||||
title=title,
|
||||
defaults={"mood_type": "negative", "uuid": uuid4()}
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("moods", "0006_add_mood_type_to_mood"),
|
||||
("scrobbles", "0057_scrobble_mood_alter_scrobble_log_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
update_moods_to_apple_list,
|
||||
migrations.RunPython.noop,
|
||||
),
|
||||
]
|
||||
@ -1,6 +1,7 @@
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
@ -15,9 +16,33 @@ BNULL = {"blank": True, "null": True}
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class MoodType(models.TextChoices):
|
||||
POSITIVE = "positive", "Positive"
|
||||
NEGATIVE = "negative", "Negative"
|
||||
|
||||
|
||||
@dataclass
|
||||
class MoodLogData(BaseLogData):
|
||||
reasons: Optional[str] = None
|
||||
mood_type: Optional[str] = None
|
||||
mood_reason_ids: Optional[list[int]] = None
|
||||
|
||||
@classmethod
|
||||
def override_fields(cls) -> dict:
|
||||
from django import forms
|
||||
from moods.models import MoodReason
|
||||
|
||||
return {
|
||||
"mood_type": forms.ChoiceField(
|
||||
choices=MoodType.choices,
|
||||
required=False,
|
||||
widget=forms.Select(attrs={"class": "form-control"}),
|
||||
),
|
||||
"mood_reason_ids": forms.ModelMultipleChoiceField(
|
||||
queryset=MoodReason.objects.all().order_by("title"),
|
||||
required=False,
|
||||
widget=forms.SelectMultiple(attrs={"size": 10}),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class Mood(ScrobblableMixin):
|
||||
@ -35,6 +60,9 @@ class Mood(ScrobblableMixin):
|
||||
format="JPEG",
|
||||
options={"quality": 75},
|
||||
)
|
||||
mood_type = models.CharField(
|
||||
max_length=20, choices=MoodType.choices, **BNULL
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
if self.title:
|
||||
@ -61,3 +89,12 @@ class Mood(ScrobblableMixin):
|
||||
if self.image:
|
||||
return self.image.url
|
||||
return ""
|
||||
|
||||
|
||||
class MoodReason(models.Model):
|
||||
uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
|
||||
title = models.CharField(max_length=255, **BNULL)
|
||||
description = models.TextField(**BNULL)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
Reference in New Issue
Block a user