Skip to content

Commit

Permalink
Merge pull request #8 from Kitware/recording-upload
Browse files Browse the repository at this point in the history
Recording Uploading
  • Loading branch information
BryonLewis authored Jan 1, 2024
2 parents 3ac641f + 37b7e50 commit 2ae1ecb
Show file tree
Hide file tree
Showing 34 changed files with 9,264 additions and 949 deletions.
64 changes: 64 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
files: ^(bats_ai)/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-case-conflict
- id: check-docstring-first
- id: check-json
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
- id: debug-statements
- id: destroyed-symlinks
- id: detect-private-key
- id: double-quote-string-fixer
- id: end-of-file-fixer
- id: mixed-line-ending
- id: trailing-whitespace

- repo: https://github.com/psf/black
rev: 23.9.1
hooks:
- id: black
args: [--config, pyproject.toml]

- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
args: [--settings-file, pyproject.toml]

- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
hooks:
- id: pyupgrade
args: [--py311-plus]

- repo: https://github.com/adamchainz/django-upgrade
rev: 1.15.0
hooks:
- id: django-upgrade
args: [--target-version, "4.1"]

- repo: https://github.com/PyCQA/autoflake
rev: v2.2.1
hooks:
- id: autoflake
args:
- --in-place
- --expand-star-imports
- --ignore-init-module-imports
- --remove-all-unused-imports
- --remove-unused-variables

- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear
- flake8-quotes
args:
- --config
- bats_ai/.flake8
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ maintenance. To non-destructively update your development stack at any time:
1. Run `docker compose pull`
2. Run `docker compose build --pull --no-cache`
3. Run `docker compose run --rm django ./manage.py migrate`

3. Run `docker compose run --rm django ./manage.py createsuperuser`
4. Run `docker compose run --rm django ./manage.py makeclient --username [email protected] --uri http://localhost:3000/`
## Develop Natively (advanced)
This configuration still uses Docker to run attached services in the background,
but allows developers to run Python code on their native system.
Expand Down
4 changes: 4 additions & 0 deletions bats_ai/.flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
# https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html?highlight=flake8#flake8
max-line-length = 176
extend-ignore = E203, E501
20 changes: 20 additions & 0 deletions bats_ai/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
import logging

from ninja import NinjaAPI
from ninja.security import HttpBearer
from oauth2_provider.models import AccessToken

from bats_ai.core.views import RecordingRouter

logger = logging.getLogger(__name__)


class GlobalAuth(HttpBearer):
def authenticate(self, request, token):
logger.warning(f'Checking Token: {token}')
print(token)
logger.warning(AccessToken.objects.get(token=token))
if AccessToken.objects.get(token=token):
logger.warning('returning token')
return token


api = NinjaAPI()

api.add_router('/recording/', RecordingRouter)
2 changes: 2 additions & 0 deletions bats_ai/core/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from .image import ImageAdmin
from .recording import RecordingAdmin

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

from bats_ai.core.models import Recording


@admin.register(Recording)
class RecordingAdmin(admin.ModelAdmin):
list_display = [
'id',
'name',
'audio_file',
'owner',
'recorded_date',
'equipment',
'comments',
'recording_location',
'grts_cell_id',
'grts_cell',
]
list_select_related = True
# list_select_related = ['owner']

search_fields = ['name']

autocomplete_fields = ['owner']
readonly_fields = ['created', 'modified']
2 changes: 1 addition & 1 deletion bats_ai/core/management/commands/makeclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ def command(username, uri):
user=user,
skip_authorization=True,
)
application.save()
application.save()
153 changes: 153 additions & 0 deletions bats_ai/core/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Generated by Django 4.1.13 on 2024-01-01 14:38

from django.conf import settings
import django.contrib.gis.db.models.fields
from django.db import migrations, models
import django.db.models.deletion
import django_extensions.db.fields
import s3_file_field.fields


class Migration(migrations.Migration):
initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Recording',
fields=[
(
'id',
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name='ID'
),
),
(
'created',
django_extensions.db.fields.CreationDateTimeField(
auto_now_add=True, verbose_name='created'
),
),
(
'modified',
django_extensions.db.fields.ModificationDateTimeField(
auto_now=True, verbose_name='modified'
),
),
('name', models.CharField(max_length=255)),
('audio_file', models.FileField(upload_to='')),
('recorded_date', models.DateField(blank=True, null=True)),
('equipment', models.TextField(blank=True, null=True)),
('comments', models.TextField(blank=True, null=True)),
(
'recording_location',
django.contrib.gis.db.models.fields.GeometryField(
blank=True, null=True, srid=0
),
),
('grts_cell_id', models.IntegerField(blank=True, null=True)),
('grts_cell', models.IntegerField(blank=True, null=True)),
(
'owner',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
options={
'get_latest_by': 'modified',
'abstract': False,
},
),
migrations.CreateModel(
name='RecordingAnnotationStatus',
fields=[
(
'id',
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name='ID'
),
),
(
'created',
django_extensions.db.fields.CreationDateTimeField(
auto_now_add=True, verbose_name='created'
),
),
(
'modified',
django_extensions.db.fields.ModificationDateTimeField(
auto_now=True, verbose_name='modified'
),
),
(
'recording_status',
models.CharField(
blank=True,
choices=[
('Complete', 'Complete'),
('In Progress', 'Inprogress'),
('Error', 'Error'),
],
help_text='Recording Annotation Status',
max_length=255,
),
),
(
'recording',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to='core.recording'
),
),
(
'user',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
options={
'get_latest_by': 'modified',
'abstract': False,
},
),
migrations.CreateModel(
name='Image',
fields=[
(
'id',
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name='ID'
),
),
(
'created',
django_extensions.db.fields.CreationDateTimeField(
auto_now_add=True, verbose_name='created'
),
),
(
'modified',
django_extensions.db.fields.ModificationDateTimeField(
auto_now=True, verbose_name='modified'
),
),
('name', models.CharField(max_length=255)),
('blob', s3_file_field.fields.S3FileField()),
('checksum', models.CharField(blank=True, max_length=128, null=True)),
(
'owner',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
options={
'get_latest_by': 'modified',
'abstract': False,
},
),
]
5 changes: 4 additions & 1 deletion bats_ai/core/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

from .image import Image
from .recording import Recording
from .recording_annotation_status import RecordingAnnotationStatus

__all__ = [
'Image',
'Recording',
'RecordingAnnotationStatus',
]
16 changes: 16 additions & 0 deletions bats_ai/core/models/recording.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.contrib.auth.models import User
from django.contrib.gis.db import models
from django_extensions.db.models import TimeStampedModel


# TimeStampedModel also provides "created" and "modified" fields
class Recording(TimeStampedModel, models.Model):
name = models.CharField(max_length=255)
audio_file = models.FileField()
owner = models.ForeignKey(User, on_delete=models.CASCADE)
recorded_date = models.DateField(blank=True, null=True)
equipment = models.TextField(blank=True, null=True)
comments = models.TextField(blank=True, null=True)
recording_location = models.GeometryField(srid=0, blank=True, null=True)
grts_cell_id = models.IntegerField(blank=True, null=True)
grts_cell = models.IntegerField(blank=True, null=True)
22 changes: 22 additions & 0 deletions bats_ai/core/models/recording_annotation_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django.contrib.auth.models import User
from django.db import models
from django_extensions.db.models import TimeStampedModel

from bats_ai.core.models import Recording


# TimeStampedModel also provides "created" and "modified" fields
class RecordingAnnotationStatus(TimeStampedModel, models.Model):
class Status(models.TextChoices):
COMPLETE = 'Complete'
INPROGRESS = 'In Progress'
ERROR = 'Error'

recording = models.ForeignKey(Recording, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
recording_status = models.CharField(
max_length=255, # If we need future states
blank=True,
help_text='Recording Annotation Status',
choices=Status.choices,
)
16 changes: 0 additions & 16 deletions bats_ai/core/rest/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
from .acoustic_batch import AcousticBatchViewSet
from .acoustic_file import AcousticFileViewSet
from .acoustic_file_batch import AcousticFileBatchViewSet
from .image import ImageViewSet
from .projects import ProjectViewSet
from .species import SpeciesViewSet
from .spectrogram import Spectrogram
from .survey_events import SurveyEventViewSet
from .surveys import SurveyViewSet

__all__ = [
'ImageViewSet',
'ProjectViewSet',
'SurveyViewSet',
'SurveyEventViewSet',
'AcousticBatchViewSet',
'AcousticFileViewSet',
'AcousticFileBatchViewSet',
'SpeciesViewSet',
'Spectrogram',
]
3 changes: 0 additions & 3 deletions bats_ai/core/rest/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from rest_framework.viewsets import ReadOnlyModelViewSet

from bats_ai.core.models import Image
from bats_ai.core.rest.user import UserSerializer
from bats_ai.core.tasks import image_compute_checksum


Expand All @@ -18,8 +17,6 @@ class Meta:
fields = ['id', 'name', 'checksum', 'created', 'owner']
read_only_fields = ['checksum', 'created']

owner = UserSerializer()


class ImageViewSet(ReadOnlyModelViewSet):
queryset = Image.objects.all()
Expand Down
1 change: 0 additions & 1 deletion bats_ai/core/templates/gallery.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,3 @@
</div>
</body>
</html>

Loading

0 comments on commit 2ae1ecb

Please sign in to comment.