Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporal Annotations #30

Merged
merged 9 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bats_ai/core/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from .annotations import AnnotationsAdmin
from .image import ImageAdmin
from .recording import RecordingAdmin
from .species import SpeciesAdmin
from .spectrogram import SpectrogramAdmin
from .temporal_annotations import TemporalAnnotationsAdmin

__all__ = [
'AnnotationsAdmin',
'ImageAdmin',
'RecordingAdmin',
'SpectrogramAdmin',
'TemporalAnnotationsAdmin',
'SpeciesAdmin',
]
17 changes: 17 additions & 0 deletions bats_ai/core/admin/species.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.contrib import admin

from bats_ai.core.models import Species


@admin.register(Species)
class SpeciesAdmin(admin.ModelAdmin):
list_display = [
'pk',
'species_code',
'family',
'genus',
'species',
'common_name',
'species_code_6',
]
list_select_related = True
18 changes: 18 additions & 0 deletions bats_ai/core/admin/temporal_annotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.contrib import admin

from bats_ai.core.models import TemporalAnnotations


@admin.register(TemporalAnnotations)
class TemporalAnnotationsAdmin(admin.ModelAdmin):
list_display = [
'pk',
'recording',
'owner',
'start_time',
'end_time',
'type',
'comments',
]
list_select_related = True
autocomplete_fields = ['owner']
43 changes: 43 additions & 0 deletions bats_ai/core/migrations/0007_temporalannotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 4.1.13 on 2024-02-15 18:08

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),
('core', '0006_alter_recording_recording_location'),
]

operations = [
migrations.CreateModel(
name='TemporalAnnotations',
fields=[
(
'id',
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name='ID'
),
),
('start_time', models.IntegerField(blank=True, null=True)),
('end_time', models.IntegerField(blank=True, null=True)),
('type', models.TextField(blank=True, null=True)),
('comments', models.TextField(blank=True, null=True)),
(
'owner',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
(
'recording',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to='core.recording'
),
),
('species', models.ManyToManyField(to='core.species')),
],
),
]
2 changes: 2 additions & 0 deletions bats_ai/core/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .recording_annotation_status import RecordingAnnotationStatus
from .species import Species
from .spectrogram import Spectrogram
from .temporal_annotations import TemporalAnnotations

__all__ = [
'Annotations',
Expand All @@ -12,4 +13,5 @@
'RecordingAnnotationStatus',
'Species',
'Spectrogram',
'TemporalAnnotations',
]
15 changes: 15 additions & 0 deletions bats_ai/core/models/temporal_annotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.contrib.auth.models import User
from django.db import models

from .recording import Recording
from .species import Species


class TemporalAnnotations(models.Model):
recording = models.ForeignKey(Recording, on_delete=models.CASCADE)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
start_time = models.IntegerField(blank=True, null=True)
end_time = models.IntegerField(blank=True, null=True)
type = models.TextField(blank=True, null=True)
comments = models.TextField(blank=True, null=True)
species = models.ManyToManyField(Species)
4 changes: 4 additions & 0 deletions bats_ai/core/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from .annotations import router as AnnotationRouter
from .recording import router as RecordingRouter
from .species import router as SpeciesRouter
from .temporal_annotations import router as TemporalAnnotationRouter

__all__ = [
'RecordingRouter',
'SpeciesRouter',
'AnnotationRouter',
'TemporalAnnotationRouter',
]
34 changes: 26 additions & 8 deletions bats_ai/core/views/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from django.http import HttpRequest
from ninja import Schema
from ninja.errors import HttpError
from ninja.pagination import RouterPaginated
from oauth2_provider.models import AccessToken

from bats_ai.core.models import Annotations, Recording

logger = logging.getLogger(__name__)

Expand All @@ -23,10 +23,28 @@ class AnnotationSchema(Schema):
comments: str


def get_owner_id(request: HttpRequest):
token = request.headers.get('Authorization').replace('Bearer ', '')
token_found = AccessToken.objects.get(token=token)
if not token_found:
raise HttpError(401, 'Authentication credentials were not provided.')
@router.get('/{id}')
def get_annotation(request: HttpRequest, id: int):
try:
annotation = Annotations.objects.get(pk=id)
recording = annotation.recording

# Check if the user owns the recording or if the recording is public
if recording.owner == request.user or recording.public:
# Query annotations associated with the recording that are owned by the current user
annotations_qs = Annotations.objects.filter(recording=recording, owner=request.user)

# Serialize the annotations using AnnotationSchema
annotations_data = [
AnnotationSchema.from_orm(annotation, owner_email=request.user.email).dict()
for annotation in annotations_qs
]

return annotations_data
else:
return {
'error': 'Permission denied. You do not own this annotation, or the associated recording is not public.'
}

return token_found.user.pk
except Recording.DoesNotExist:
return {'error': 'Recording not found'}
Loading
Loading