From f8844ce091a9ce9ef38e7419aa881a56ab752f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Sat, 18 Feb 2023 21:12:18 +0100 Subject: [PATCH] Add support for device info Closes #49 --- CHANGELOG.md | 1 + games/forms.py | 9 +++- .../migrations/0014_device_session_device.py | 52 +++++++++++++++++++ games/models.py | 21 ++++++++ games/templates/base.html | 1 + games/urls.py | 1 + games/views.py | 21 +++++++- 7 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 games/migrations/0014_device_session_device.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f9e104..3dca0e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Unreleased +* Add support for device info (https://git.kucharczyk.xyz/lukas/timetracker/issues/49) * Add support for purchase ownership information (https://git.kucharczyk.xyz/lukas/timetracker/issues/48) * Add support for purchase prices * Add support for game editions (https://git.kucharczyk.xyz/lukas/timetracker/issues/28) diff --git a/games/forms.py b/games/forms.py index 08662ea..93db2a2 100644 --- a/games/forms.py +++ b/games/forms.py @@ -1,6 +1,6 @@ from django import forms -from games.models import Game, Platform, Purchase, Session, Edition +from games.models import Game, Platform, Purchase, Session, Edition, Device class SessionForm(forms.ModelForm): @@ -15,6 +15,7 @@ class SessionForm(forms.ModelForm): "timestamp_start", "timestamp_end", "duration_manual", + "device", "note", ] @@ -52,3 +53,9 @@ class PlatformForm(forms.ModelForm): class Meta: model = Platform fields = ["name", "group"] + + +class DeviceForm(forms.ModelForm): + class Meta: + model = Device + fields = ["name", "type"] diff --git a/games/migrations/0014_device_session_device.py b/games/migrations/0014_device_session_device.py new file mode 100644 index 0000000..58aaa41 --- /dev/null +++ b/games/migrations/0014_device_session_device.py @@ -0,0 +1,52 @@ +# Generated by Django 4.1.5 on 2023-02-18 19:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("games", "0013_purchase_ownership_type"), + ] + + operations = [ + migrations.CreateModel( + name="Device", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ( + "type", + models.CharField( + choices=[ + ("pc", "PC"), + ("co", "Console"), + ("ha", "Handheld"), + ("mo", "Mobile"), + ("sbc", "Single-board computer"), + ], + default="pc", + max_length=3, + ), + ), + ], + ), + migrations.AddField( + model_name="session", + name="device", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="games.device", + ), + ), + ] diff --git a/games/models.py b/games/models.py index 6070c4a..ac637e1 100644 --- a/games/models.py +++ b/games/models.py @@ -81,6 +81,7 @@ class Session(models.Model): timestamp_end = models.DateTimeField(blank=True, null=True) duration_manual = models.DurationField(blank=True, null=True, default=timedelta(0)) duration_calculated = models.DurationField(blank=True, null=True) + device = models.ForeignKey("Device", on_delete=models.CASCADE, null=True) note = models.TextField(blank=True, null=True) objects = SessionQuerySet.as_manager() @@ -118,3 +119,23 @@ class Session(models.Model): else: self.duration_calculated = timedelta(0) super(Session, self).save(*args, **kwargs) + + +class Device(models.Model): + PC = "pc" + CONSOLE = "co" + HANDHELD = "ha" + MOBILE = "mo" + SBC = "sbc" + DEVICE_TYPES = [ + (PC, "PC"), + (CONSOLE, "Console"), + (HANDHELD, "Handheld"), + (MOBILE, "Mobile"), + (SBC, "Single-board computer"), + ] + name = models.CharField(max_length=255) + type = models.CharField(max_length=3, choices=DEVICE_TYPES, default=PC) + + def __str__(self): + return f"{self.name} ({self.get_type_display()})" diff --git a/games/templates/base.html b/games/templates/base.html index efd432e..5a664f5 100644 --- a/games/templates/base.html +++ b/games/templates/base.html @@ -34,6 +34,7 @@ {% endif %} {% if purchase_available %}
  • New Session
  • +
  • New Device
  • {% endif %} {% if session_count > 0 %}
  • All Sessions
  • diff --git a/games/urls.py b/games/urls.py index bfc7dec..a96f555 100644 --- a/games/urls.py +++ b/games/urls.py @@ -30,6 +30,7 @@ urlpatterns = [ ), path("add-purchase/", views.add_purchase, name="add_purchase"), path("add-edition/", views.add_edition, name="add_edition"), + path("add-device/", views.add_device, name="add_device"), path("edit-session/", views.edit_session, name="edit_session"), path("list-sessions/", views.list_sessions, name="list_sessions"), path( diff --git a/games/views.py b/games/views.py index 3ee787f..167a1a7 100644 --- a/games/views.py +++ b/games/views.py @@ -6,7 +6,14 @@ from common.time import now as now_with_tz from django.conf import settings from django.shortcuts import redirect, render -from .forms import GameForm, PlatformForm, PurchaseForm, SessionForm, EditionForm +from .forms import ( + GameForm, + PlatformForm, + PurchaseForm, + SessionForm, + EditionForm, + DeviceForm, +) from .models import Game, Platform, Purchase, Session, Edition @@ -160,5 +167,17 @@ def add_platform(request): return render(request, "add.html", context) +def add_device(request): + context = {} + form = DeviceForm(request.POST or None) + if form.is_valid(): + form.save() + return redirect("index") + + context["form"] = form + context["title"] = "Add New Device" + return render(request, "add.html", context) + + def index(request): return redirect("list_sessions_recent")