From 117157e3aeae54ee3db27d54fec0b02fa0f24304 Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Mon, 6 Feb 2023 19:30:58 -0500 Subject: [PATCH] Fix audioscrobbler import bug Issue was not having a user so we couldn't set a timezone. All fixed now --- vrobbler/apps/profiles/models.py | 6 +++++ .../0017_audioscrobblertsvimport_user.py | 26 +++++++++++++++++++ vrobbler/apps/scrobbles/models.py | 6 ++++- vrobbler/apps/scrobbles/tsv.py | 6 +++-- vrobbler/apps/scrobbles/views.py | 11 +++++++- 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 vrobbler/apps/scrobbles/migrations/0017_audioscrobblertsvimport_user.py diff --git a/vrobbler/apps/profiles/models.py b/vrobbler/apps/profiles/models.py index ef7f12e..adc125b 100644 --- a/vrobbler/apps/profiles/models.py +++ b/vrobbler/apps/profiles/models.py @@ -1,3 +1,5 @@ +import pytz + from django.contrib.auth import get_user_model from django.db import models from django_extensions.db.models import TimeStampedModel @@ -16,3 +18,7 @@ class UserProfile(TimeStampedModel): def __str__(self): return f"User profile for {self.user}" + + @property + def tzinfo(self): + return pytz.timezone(self.timezone) diff --git a/vrobbler/apps/scrobbles/migrations/0017_audioscrobblertsvimport_user.py b/vrobbler/apps/scrobbles/migrations/0017_audioscrobblertsvimport_user.py new file mode 100644 index 0000000..9c5e761 --- /dev/null +++ b/vrobbler/apps/scrobbles/migrations/0017_audioscrobblertsvimport_user.py @@ -0,0 +1,26 @@ +# Generated by Django 4.1.5 on 2023-02-07 00:07 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('scrobbles', '0016_audioscrobblertsvimport_process_count'), + ] + + operations = [ + migrations.AddField( + model_name='audioscrobblertsvimport', + name='user', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/vrobbler/apps/scrobbles/models.py b/vrobbler/apps/scrobbles/models.py index 60e59d0..2e80a2f 100644 --- a/vrobbler/apps/scrobbles/models.py +++ b/vrobbler/apps/scrobbles/models.py @@ -24,6 +24,7 @@ class AudioScrobblerTSVImport(TimeStampedModel): uuid = instance.uuid return f'audioscrobbler-uploads/{uuid}.{extension}' + user = models.ForeignKey(User, on_delete=models.DO_NOTHING, **BNULL) uuid = models.UUIDField(editable=False, default=uuid4) tsv_file = models.FileField(upload_to=get_path, **BNULL) processed_on = models.DateTimeField(**BNULL) @@ -48,7 +49,10 @@ class AudioScrobblerTSVImport(TimeStampedModel): logger.info(f"{self} already processed on {self.processed_on}") return - scrobbles = process_audioscrobbler_tsv_file(self.tsv_file.path) + tz = None + if self.user: + tz = self.user.profile.tzinfo + scrobbles = process_audioscrobbler_tsv_file(self.tsv_file.path, tz=tz) if scrobbles: self.process_log = f"Created {len(scrobbles)} scrobbles" for scrobble in scrobbles: diff --git a/vrobbler/apps/scrobbles/tsv.py b/vrobbler/apps/scrobbles/tsv.py index ccf7d85..5096d68 100644 --- a/vrobbler/apps/scrobbles/tsv.py +++ b/vrobbler/apps/scrobbles/tsv.py @@ -9,9 +9,11 @@ from scrobbles.models import Scrobble logger = logging.getLogger(__name__) -def process_audioscrobbler_tsv_file(file_path): +def process_audioscrobbler_tsv_file(file_path, tz=None): """Takes a path to a file of TSV data and imports it as past scrobbles""" new_scrobbles = [] + if not tz: + tz = pytz.utc with open(file_path) as infile: source = 'Audioscrobbler File' @@ -70,7 +72,7 @@ def process_audioscrobbler_tsv_file(file_path): track.save() timestamp = datetime.utcfromtimestamp(int(row[6])).replace( - tzinfo=pytz.utc + tzinfo=tz ) source = 'Audioscrobbler File' diff --git a/vrobbler/apps/scrobbles/views.py b/vrobbler/apps/scrobbles/views.py index fabb2c1..d497db2 100644 --- a/vrobbler/apps/scrobbles/views.py +++ b/vrobbler/apps/scrobbles/views.py @@ -4,6 +4,7 @@ from datetime import datetime import pytz from django.conf import settings +from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models.fields import timezone from django.http import FileResponse, HttpResponseRedirect, JsonResponse from django.urls import reverse, reverse_lazy @@ -160,12 +161,20 @@ class JsonableResponseMixin: return JsonResponse(data) -class AudioScrobblerImportCreateView(JsonableResponseMixin, CreateView): +class AudioScrobblerImportCreateView( + LoginRequiredMixin, JsonableResponseMixin, CreateView +): model = AudioScrobblerTSVImport fields = ['tsv_file'] template_name = 'scrobbles/upload_form.html' success_url = reverse_lazy('vrobbler-home') + def form_valid(self, form): + self.object = form.save(commit=False) + self.object.user = self.request.user + self.object.save() + return HttpResponseRedirect(self.get_success_url()) + @csrf_exempt @api_view(['GET'])