瀏覽代碼

Fix audioscrobbler import bug

Issue was not having a user so we couldn't set a timezone. All fixed now
Colin Powell 2 年之前
父節點
當前提交
117157e3ae

+ 6 - 0
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)

+ 26 - 0
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,
+            ),
+        ),
+    ]

+ 5 - 1
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:

+ 4 - 2
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'
 

+ 10 - 1
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'])