11from datetime import datetime
22import json
33import logging
4+ from typing import List , Optional
45
56from django .contrib .auth .models import User
67from django .contrib .gis .geos import Point
8+ from django .contrib .postgres .aggregates import ArrayAgg
79from django .core .files .storage import default_storage
810from django .db .models import Q
911from django .http import HttpRequest
1618 CompressedSpectrogram ,
1719 Recording ,
1820 RecordingAnnotation ,
21+ RecordingTag ,
1922 SequenceAnnotations ,
2023 Species ,
2124)
25+ from bats_ai .core .views .recording_tag import RecordingTagSchema
2226from bats_ai .core .views .sequence_annotations import (
2327 SequenceAnnotationSchema ,
2428 UpdateSequenceAnnotationSchema ,
@@ -43,23 +47,25 @@ class RecordingSchema(Schema):
4347 recording_location : str | None
4448 grts_cell_id : int | None
4549 grts_cell : int | None
50+ tags : list [RecordingTagSchema ] = []
4651
4752
4853class RecordingUploadSchema (Schema ):
4954 name : str
5055 recorded_date : str
5156 recorded_time : str
52- equipment : str | None
53- comments : str | None
54- latitude : float = None
55- longitude : float = None
56- gridCellId : int = None
57- publicVal : bool = None
58- site_name : str = None
59- software : str = None
60- detector : str = None
61- species_list : str = None
62- unusual_occurrences : str = None
57+ equipment : str | None = None
58+ comments : str | None = None
59+ latitude : float | None = None
60+ longitude : float | None = None
61+ gridCellId : int | None = None
62+ publicVal : bool | None = None
63+ site_name : str | None = None
64+ software : str | None = None
65+ detector : str | None = None
66+ species_list : str | None = None
67+ unusual_occurrences : str | None = None
68+ tags : Optional [List [str ]] = None
6369
6470
6571class RecordingAnnotationSchema (Schema ):
@@ -150,6 +156,12 @@ def create_recording(
150156 species_list = payload .species_list ,
151157 unusual_occurrences = payload .unusual_occurrences ,
152158 )
159+ recording .save ()
160+
161+ if payload .tags :
162+ for tag in payload .tags :
163+ tag , _ = RecordingTag .objects .get_or_create (user = request .user , text = tag )
164+ recording .tags .add (tag )
153165
154166 recording .save ()
155167 # Start generating recording as soon as created
@@ -193,6 +205,16 @@ def update_recording(request: HttpRequest, id: int, recording_data: RecordingUpl
193205 recording .species_list = recording_data .species_list
194206 if recording_data .unusual_occurrences :
195207 recording .unusual_occurrences = recording_data .unusual_occurrences
208+ if recording_data .tags :
209+ existing_tags = recording .tags .all ()
210+ for tag in recording_data .tags :
211+ tag , _ = RecordingTag .objects .get_or_create (user = request .user , text = tag )
212+ if tag not in existing_tags :
213+ recording .tags .add (tag )
214+ # Remove any tags that are not in the updated list
215+ for existing_tag in existing_tags :
216+ if existing_tag .text not in recording_data .tags :
217+ recording .tags .remove (existing_tag )
196218
197219 recording .save ()
198220
@@ -230,10 +252,15 @@ def get_recordings(request: HttpRequest, public: bool | None = None):
230252 recordings = (
231253 Recording .objects .filter (public = True )
232254 .exclude (Q (owner = request .user ) | Q (spectrogram__isnull = True ))
255+ .annotate (tags_text = ArrayAgg ('tags__text' ))
233256 .values ()
234257 )
235258 else :
236- recordings = Recording .objects .filter (owner = request .user ).values ()
259+ recordings = (
260+ Recording .objects .filter (owner = request .user )
261+ .annotate (tags_text = ArrayAgg ('tags__text' ))
262+ .values ()
263+ )
237264
238265 # TODO with larger dataset it may be better to do this in a queryset instead of python
239266 for recording in recordings :
@@ -270,7 +297,9 @@ def get_recordings(request: HttpRequest, public: bool | None = None):
270297def get_recording (request : HttpRequest , id : int ):
271298 # Filter recordings based on the owner's id or public=True
272299 try :
273- recordings = Recording .objects .filter (pk = id ).values ()
300+ recordings = (
301+ Recording .objects .filter (pk = id ).annotate (tags_text = ArrayAgg ('tags__text' )).values ()
302+ )
274303 if len (recordings ) > 0 :
275304 recording = recordings [0 ]
276305
@@ -312,7 +341,6 @@ def get_recording(request: HttpRequest, id: int):
312341 RecordingAnnotationSchema .from_orm (fileAnnotation ).dict ()
313342 for fileAnnotation in fileAnnotations
314343 ]
315-
316344 return recording
317345 else :
318346 return {'error' : 'Recording not found' }
0 commit comments