[tasks] Add unit handling to weigh-ins
All checks were successful
build & deploy / test (push) Successful in 1m44s
build & deploy / build-and-deploy (push) Successful in 26s

This commit is contained in:
2026-05-21 09:42:40 -04:00
parent 9d3f7f434f
commit 0d6b2c4afc
5 changed files with 120 additions and 16 deletions

View File

@ -35,6 +35,7 @@ class UserProfileForm(forms.ModelForm):
"enable_public_widgets",
"widget_custom_css",
"home_scrobble_limit",
"weigh_in_units",
]
widgets = {
"lastfm_password": forms.PasswordInput(render_value=True),

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.29 on 2026-05-21 13:38
from django.db import migrations, models
import profiles.models
class Migration(migrations.Migration):
dependencies = [
("profiles", "0031_add_home_scrobble_limit"),
]
operations = [
migrations.AddField(
model_name="userprofile",
name="weigh_in_units",
field=models.CharField(
choices=profiles.models.WeighUnit.choices,
default=profiles.models.WeighUnit.METRIC,
max_length=16,
),
),
]

View File

@ -16,6 +16,11 @@ BNULL = {"blank": True, "null": True}
logger = logging.getLogger(__name__)
class WeighUnit(models.TextChoices):
METRIC = "metric", "Metric (kg, cm)"
IMPERIAL = "imperial", "Imperial (lbs, in)"
class UserProfile(TimeStampedModel):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
timezone = models.CharField(
@ -66,6 +71,12 @@ class UserProfile(TimeStampedModel):
home_scrobble_limit = models.IntegerField(default=20)
weigh_in_units = models.CharField(
max_length=16,
choices=WeighUnit.choices,
default=WeighUnit.METRIC,
)
def __str__(self):
return f"User profile for {self.user}"

View File

@ -10,28 +10,28 @@ from tasks.models import Task
logger = logging.getLogger(__name__)
FLOAT_COLUMNS = {
"WEIGHT": "weight_kg",
"WEIGHT": "weight",
"BMI": "bmi",
"BODY_FAT": "body_fat_pct",
"BONE": "bone_kg",
"MUSCLE": "muscle_kg",
"WATER": "water_pct",
"BODY_FAT": "body_fat",
"BONE": "bone",
"MUSCLE": "muscle",
"WATER": "water",
"VISCERAL_FAT": "visceral_fat",
"WAIST": "waist_cm",
"WAIST": "waist",
"CALORIES": "calories",
"BMR": "bmr",
"TDEE": "tdee",
"HEART_RATE": "heart_rate",
"CHEST": "chest_cm",
"BICEPS": "biceps_cm",
"NECK": "neck_cm",
"THIGH": "thigh_cm",
"HIPS": "hips_cm",
"CALIPER": "caliper_mm",
"CALIPER_1": "caliper_1_mm",
"CALIPER_2": "caliper_2_mm",
"CALIPER_3": "caliper_3_mm",
"LBM": "lbm_kg",
"CHEST": "chest",
"BICEPS": "biceps",
"NECK": "neck",
"THIGH": "thigh",
"HIPS": "hips",
"CALIPER": "caliper",
"CALIPER_1": "caliper_1",
"CALIPER_2": "caliper_2",
"CALIPER_3": "caliper_3",
"LBM": "lbm",
"WHR": "whr",
"WHTR": "whtr",
}
@ -83,6 +83,8 @@ def import_scale_csv(file_path, user_id):
if comment:
log_dict["comment"] = comment
log_dict["unit_type"] = user.profile.weigh_in_units
existing = Scrobble.objects.filter(
timestamp=start,
task=weigh_in,

View File

@ -6,6 +6,24 @@
{% block title %}{{object.name}}{% endblock %}
{% block head_extra %}
<style>
dl { border:none; }
dt {
background: #333;
color: #fff;
}
dd {
float:left;
margin: 2px;
padding: 4px;
min-height: 1em;
border: none;
}
</style>
{% endblock %}
{% block lists %}
<div class="row">
@ -20,6 +38,54 @@
{% if object.media_type == "Track" %}
<p class="text-muted small">Source: {{ object.source }}{% if object.log.mopidy_source %} ({{ object.log.mopidy_source|capfirst }}){% endif %}</p>
{% endif %}
{% if object.media_type == "Task" and object.log.weight %}
<div class="mb-3">
<dl class="row" style="max-width: 400px;">
<dt class="col-sm-5">Weight</dt>
<dd class="col-sm-7">{{ object.log.weight }} {% if object.log.unit_type == "imperial" %}lbs{% else %}kg{% endif %}</dd>
{% if object.log.body_fat %}
<dt class="col-sm-5">Body Fat</dt>
<dd class="col-sm-7">{{ object.log.body_fat }}%</dd>
{% endif %}
{% if object.log.bmi %}
<dt class="col-sm-5">BMI</dt>
<dd class="col-sm-7">{{ object.log.bmi }}</dd>
{% endif %}
{% if object.log.muscle %}
<dt class="col-sm-5">Muscle</dt>
<dd class="col-sm-7">{{ object.log.muscle }} {% if object.log.unit_type == "imperial" %}lbs{% else %}kg{% endif %}</dd>
{% endif %}
{% if object.log.bone %}
<dt class="col-sm-5">Bone</dt>
<dd class="col-sm-7">{{ object.log.bone }} {% if object.log.unit_type == "imperial" %}lbs{% else %}kg{% endif %}</dd>
{% endif %}
{% if object.log.water %}
<dt class="col-sm-5">Water</dt>
<dd class="col-sm-7">{{ object.log.water }}%</dd>
{% endif %}
{% if object.log.visceral_fat %}
<dt class="col-sm-5">Visceral Fat</dt>
<dd class="col-sm-7">{{ object.log.visceral_fat }}</dd>
{% endif %}
{% if object.log.waist %}
<dt class="col-sm-5">Waist</dt>
<dd class="col-sm-7">{{ object.log.waist }} {% if object.log.unit_type == "imperial" %}in{% else %}cm{% endif %}</dd>
{% endif %}
{% if object.log.lbm %}
<dt class="col-sm-5">Lean Mass</dt>
<dd class="col-sm-7">{{ object.log.lbm }} {% if object.log.unit_type == "imperial" %}lbs{% else %}kg{% endif %}</dd>
{% endif %}
{% if object.log.calories %}
<dt class="col-sm-5">Calories</dt>
<dd class="col-sm-7">{{ object.log.calories }}</dd>
{% endif %}
{% if object.log.comment %}
<dt class="col-sm-5">Comment</dt>
<dd class="col-sm-7">{{ object.log.comment }}</dd>
{% endif %}
</dl>
</div>
{% endif %}
{% if object.media_type == "Task" and object.logdata.description %}
<p>{{ object.logdata.description }}</p>
{% endif %}