From 628b7b28cea93262414edda79b6cbc48762e4d0b Mon Sep 17 00:00:00 2001 From: Roman Dvorak Date: Thu, 28 Mar 2024 00:13:53 +0100 Subject: [PATCH] dosportal updates --- DOSPORTAL/PART_organizations/__init__.py | 0 DOSPORTAL/PART_organizations/urls.py | 15 ++ .../PART_organizations/views_organizations.py | 20 ++ DOSPORTAL/admin.py | 6 + DOSPORTAL/forms.py | 76 ++++-- DOSPORTAL/migrations/0001_initial.py | 227 ++++++++++++++++-- ...ufacturer_name_detectormanufacturer_url.py | 25 -- DOSPORTAL/migrations/0002_spectrumdata.py | 27 +++ ...ctor_manufacturer_detectortype_and_more.py | 36 --- .../migrations/0003_spectrumdata_spectrum.py | 19 ++ ...0004_alter_measurement_measurement_type.py | 18 -- ...etadata_spectrumdata_particles_and_more.py | 31 +++ ...05_alter_spectrumdata_metadata_and_more.py | 24 ++ .../migrations/0005_measurement_public.py | 18 -- ..._measurement_base_location_alt_and_more.py | 38 --- ...integration_alter_spectrumdata_spectrum.py | 23 ++ .../migrations/0007_alter_record_detector.py | 19 -- DOSPORTAL/migrations/0007_record_author.py | 21 ++ ...d_log_filename_alter_record_measurement.py | 25 -- ..._measurement_base_location_alt_and_more.py | 28 --- ...ght_measurementdataflight_record_flight.py | 57 ----- .../migrations/0011_flight_trajectory_file.py | 20 -- .../migrations/0012_alter_record_flight.py | 19 -- ..._callsign_flight_flight_number_and_more.py | 27 --- ...remove_record_flight_measurement_flight.py | 23 -- .../0015_alter_measurement_flight.py | 19 -- .../0016_record_record_type_and_more.py | 60 ----- ...orts_municipality_airports_web_and_more.py | 28 --- DOSPORTAL/migrations/0018_detectorcalib.py | 31 --- .../0019_remove_detectorcalib_author.py | 17 -- DOSPORTAL/migrations/0020_detector_calib.py | 19 -- ..._campaign_alter_detector_calib_and_more.py | 35 --- .../0022_alter_measurement_campaign_name.py | 18 -- .../0023_alter_detectorcalib_cabib.py | 18 -- ..._rename_compaings_measurement_campaings.py | 18 -- DOSPORTAL/migrations/0025_detectorlogblock.py | 30 --- ...detectorlogbook_delete_detectorlogblock.py | 33 --- .../0027_alter_measurement_description.py | 19 -- ...calib_alter_measurement_author_and_more.py | 42 ---- .../migrations/0029_carimodel_flight_cari.py | 30 --- ...er_flight_cari_alter_measurement_flight.py | 24 -- .../migrations/0031_detectorlogbook_public.py | 18 -- ...a_alter_detectorlogbook_public_and_more.py | 29 --- .../0033_detector_manufactured_date.py | 18 -- ...034_record_metadata_alter_detector_data.py | 23 -- ..._record_time_end_record_record_duration.py | 22 -- DOSPORTAL/models.py | 189 ++++++++++++++- DOSPORTAL/tasks.py | 9 + DOSPORTAL/urls.py | 19 +- DOSPORTAL/users/urls.py | 14 ++ DOSPORTAL/views_detectors.py | 12 +- DOSPORTAL/views_record.py | 112 +++++++-- Dockerfile | 2 +- data/media/default_user_profileimage.jpg | Bin 0 -> 7852 bytes docker-compose.yml | 44 ++-- 55 files changed, 809 insertions(+), 985 deletions(-) create mode 100644 DOSPORTAL/PART_organizations/__init__.py create mode 100644 DOSPORTAL/PART_organizations/urls.py create mode 100644 DOSPORTAL/PART_organizations/views_organizations.py delete mode 100644 DOSPORTAL/migrations/0002_detectormanufacturer_name_detectormanufacturer_url.py create mode 100644 DOSPORTAL/migrations/0002_spectrumdata.py delete mode 100644 DOSPORTAL/migrations/0003_remove_detector_manufacturer_detectortype_and_more.py create mode 100644 DOSPORTAL/migrations/0003_spectrumdata_spectrum.py delete mode 100644 DOSPORTAL/migrations/0004_alter_measurement_measurement_type.py create mode 100644 DOSPORTAL/migrations/0004_spectrumdata_metadata_spectrumdata_particles_and_more.py create mode 100644 DOSPORTAL/migrations/0005_alter_spectrumdata_metadata_and_more.py delete mode 100644 DOSPORTAL/migrations/0005_measurement_public.py delete mode 100644 DOSPORTAL/migrations/0006_measurement_base_location_alt_and_more.py create mode 100644 DOSPORTAL/migrations/0006_spectrumdata_integration_alter_spectrumdata_spectrum.py delete mode 100644 DOSPORTAL/migrations/0007_alter_record_detector.py create mode 100644 DOSPORTAL/migrations/0007_record_author.py delete mode 100644 DOSPORTAL/migrations/0008_record_log_filename_alter_record_measurement.py delete mode 100644 DOSPORTAL/migrations/0009_alter_measurement_base_location_alt_and_more.py delete mode 100644 DOSPORTAL/migrations/0010_airports_flight_measurementdataflight_record_flight.py delete mode 100644 DOSPORTAL/migrations/0011_flight_trajectory_file.py delete mode 100644 DOSPORTAL/migrations/0012_alter_record_flight.py delete mode 100644 DOSPORTAL/migrations/0013_rename_callsign_flight_flight_number_and_more.py delete mode 100644 DOSPORTAL/migrations/0014_remove_record_flight_measurement_flight.py delete mode 100644 DOSPORTAL/migrations/0015_alter_measurement_flight.py delete mode 100644 DOSPORTAL/migrations/0016_record_record_type_and_more.py delete mode 100644 DOSPORTAL/migrations/0017_airports_municipality_airports_web_and_more.py delete mode 100644 DOSPORTAL/migrations/0018_detectorcalib.py delete mode 100644 DOSPORTAL/migrations/0019_remove_detectorcalib_author.py delete mode 100644 DOSPORTAL/migrations/0020_detector_calib.py delete mode 100644 DOSPORTAL/migrations/0021_measurement_campaign_alter_detector_calib_and_more.py delete mode 100644 DOSPORTAL/migrations/0022_alter_measurement_campaign_name.py delete mode 100644 DOSPORTAL/migrations/0023_alter_detectorcalib_cabib.py delete mode 100644 DOSPORTAL/migrations/0024_rename_compaings_measurement_campaings.py delete mode 100644 DOSPORTAL/migrations/0025_detectorlogblock.py delete mode 100644 DOSPORTAL/migrations/0026_detectorlogbook_delete_detectorlogblock.py delete mode 100644 DOSPORTAL/migrations/0027_alter_measurement_description.py delete mode 100644 DOSPORTAL/migrations/0028_alter_detector_calib_alter_measurement_author_and_more.py delete mode 100644 DOSPORTAL/migrations/0029_carimodel_flight_cari.py delete mode 100644 DOSPORTAL/migrations/0030_alter_flight_cari_alter_measurement_flight.py delete mode 100644 DOSPORTAL/migrations/0031_detectorlogbook_public.py delete mode 100644 DOSPORTAL/migrations/0032_detector_data_alter_detectorlogbook_public_and_more.py delete mode 100644 DOSPORTAL/migrations/0033_detector_manufactured_date.py delete mode 100644 DOSPORTAL/migrations/0034_record_metadata_alter_detector_data.py delete mode 100644 DOSPORTAL/migrations/0035_remove_record_time_end_record_record_duration.py create mode 100644 DOSPORTAL/users/urls.py create mode 100644 data/media/default_user_profileimage.jpg diff --git a/DOSPORTAL/PART_organizations/__init__.py b/DOSPORTAL/PART_organizations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/DOSPORTAL/PART_organizations/urls.py b/DOSPORTAL/PART_organizations/urls.py new file mode 100644 index 0000000..66dcde0 --- /dev/null +++ b/DOSPORTAL/PART_organizations/urls.py @@ -0,0 +1,15 @@ +from django.contrib import admin +from django.urls import path, include +from django.views.generic.base import TemplateView +import uuid + +from . import views_organizations + +urlpatterns = [ + + + path(r'', views_organizations.organization_profile, name='organization-detail'), + path(r'', views_organizations.organization_profile, name='organization-detail'), + path(r'', views_organizations.organization_profile, name='organization'), + +] \ No newline at end of file diff --git a/DOSPORTAL/PART_organizations/views_organizations.py b/DOSPORTAL/PART_organizations/views_organizations.py new file mode 100644 index 0000000..297d8d6 --- /dev/null +++ b/DOSPORTAL/PART_organizations/views_organizations.py @@ -0,0 +1,20 @@ +import django +from django.shortcuts import render, redirect +from django import forms +from django.http import HttpResponse, JsonResponse +from django.views import generic +from ..models import (Organization, OrganizationUser) + +from django.shortcuts import get_object_or_404, redirect, render +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User + + +@login_required +def organization_profile(request, pk = None, slug = None): + if pk: + organization = Organization.objects.get(pk=pk) + elif slug: + organization = Organization.objects.get(slug=slug) + + return render(request, 'organizations/organization_profile.html', {'organization':organization}) \ No newline at end of file diff --git a/DOSPORTAL/admin.py b/DOSPORTAL/admin.py index 25dccca..3dde1cf 100644 --- a/DOSPORTAL/admin.py +++ b/DOSPORTAL/admin.py @@ -38,6 +38,7 @@ def user_count(self, obj): +admin.site.register(Profile) admin.site.register(DetectorManufacturer) admin.site.register(measurement) admin.site.register(Organization, OrganizationAdmin) @@ -53,6 +54,11 @@ def user_count(self, obj): admin.site.register(measurement_campaign) +admin.site.register(Trajectory) +admin.site.register(TrajectoryPoint) + +admin.site.register(SpectrumData) + from django_q import models as q_models from django_q import admin as q_admin diff --git a/DOSPORTAL/forms.py b/DOSPORTAL/forms.py index a3b0839..b1900bd 100644 --- a/DOSPORTAL/forms.py +++ b/DOSPORTAL/forms.py @@ -1,5 +1,31 @@ from django import forms -from .models import Detector, record +from .models import Detector, record, Profile, Organization + +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm + + +class UserRegisterForm(UserCreationForm): + email = forms.EmailField() + + class Meta: + model = User + fields = ['username', 'email', 'password1', 'password2'] + +# Create a UserUpdateForm to update a username and email +class UserUpdateForm(forms.ModelForm): + email = forms.EmailField() + + class Meta: + model = User + fields = ['username', 'email'] + +# Create a ProfileUpdateForm to update image. +class ProfileUpdateForm(forms.ModelForm): + class Meta: + model = Profile + fields = ['image'] class DetectorLogblogForm(forms.Form): @@ -14,17 +40,24 @@ class DetectorLogblogForm(forms.Form): class RecordForm(forms.ModelForm): - log_file = forms.FileField( - required=False, - widget=forms.widgets.FileInput(attrs={ - 'class': 'form-control', - }), - label="Log file", - help_text="Select a log file to upload." - #widget=forms.FileInput(attrs={ - # 'class': 'form-control', - #}) - ) + + user = None + def __init__(self,*args, user=None, **kwargs): + super(RecordForm, self).__init__(*args, **kwargs) + self.user = user + + + # log_file = forms.FileField( + # required=False, + # widget=forms.widgets.FileInput(attrs={ + # 'class': 'form-control', + # }), + # label="Log file", + # help_text="Select a log file to upload." + # #widget=forms.FileInput(attrs={ + # # 'class': 'form-control', + # #}) + # ) detector = forms.ModelChoiceField( queryset=Detector.objects.all(), @@ -37,13 +70,22 @@ class RecordForm(forms.ModelForm): ) record_type = forms.ChoiceField( - choices=record.RECORD_TYPES, - widget=forms.Select(attrs={ - 'class': 'form-control', - }) + choices=record.RECORD_TYPES ) + belongs = forms.ModelChoiceField( + queryset=Organization.objects.exclude(user_organizations__user=user), + required=True, + label="Belongs to", + help_text="Select organization this record belongs to." + ) class Meta: model = record - exclude = ("time_end", "measurement", "log_filename", "metadata", "duration", "time_start", "record_duration") + exclude = ("time_end", "measurement", "log_original_filename", "metadata", "duration", "time_start", "record_duration") + + +class DetectorEditForm(forms.ModelForm): + class Meta: + model = Detector + fields = ["name", "type", 'sn', "calib", "manufactured_date", "data", "owner", "access"] \ No newline at end of file diff --git a/DOSPORTAL/migrations/0001_initial.py b/DOSPORTAL/migrations/0001_initial.py index 0061480..b8c29e0 100644 --- a/DOSPORTAL/migrations/0001_initial.py +++ b/DOSPORTAL/migrations/0001_initial.py @@ -1,9 +1,11 @@ -# Generated by Django 4.2.1 on 2023-06-05 08:02 +# Generated by Django 4.2.11 on 2024-03-27 09:18 import DOSPORTAL.models from django.conf import settings +import django.contrib.gis.db.models.fields from django.db import migrations, models import django.db.models.deletion +import martor.models import uuid @@ -16,12 +18,57 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='Airports', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('name', models.CharField()), + ('code_iata', models.CharField(null=True, unique=True)), + ('code_icao', models.CharField(null=True, unique=True)), + ('lat', models.FloatField(null=True)), + ('lon', models.FloatField(null=True)), + ('alt', models.FloatField(null=True)), + ('municipality', models.CharField(null=True)), + ('web', models.CharField(null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='CARImodel', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('data', models.JSONField()), + ], + options={ + 'abstract': False, + }, + ), migrations.CreateModel( name='Detector', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), ('sn', models.CharField(max_length=80)), ('name', models.CharField(max_length=150, verbose_name='Detector name')), + ('manufactured_date', models.DateField(blank=True, help_text='Date when detector was manufactured', null=True, verbose_name='Manufactured date')), + ('data', models.JSONField(help_text='Detector metadata, used for advanced data processing and maintaining', verbose_name='Detector metadata')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='DetectorCalib', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('name', models.CharField(verbose_name='Calibration name')), + ('description', models.TextField(verbose_name='Description of calibration status')), + ('date', models.DateTimeField()), + ('coef0', models.FloatField(default=0.0, verbose_name='Coefficient 0 (offset)')), + ('coef1', models.FloatField(default=1, verbose_name='Coefficient 1, (linear)')), + ('coef2', models.FloatField(default=0.0, verbose_name='Coefficient 2, (quadratic)')), + ('cabib', models.JSONField(null=True, verbose_name='Slozky kalibrace, json')), ], options={ 'abstract': False, @@ -31,44 +78,196 @@ class Migration(migrations.Migration): name='DetectorManufacturer', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('name', models.CharField(max_length=80)), + ('url', models.URLField()), ], options={ 'abstract': False, }, ), migrations.CreateModel( - name='measurement', + name='Flight', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('flight_number', models.CharField()), + ('departure_time', models.DateTimeField(null=True, verbose_name='Scheduled departure time')), + ('trajectory_file', models.FileField(upload_to=DOSPORTAL.models.Flight.user_directory_path, verbose_name='Trajectory log')), + ('cari', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.carimodel')), + ('land', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='landing', to='DOSPORTAL.airports')), + ('takeoff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='takeoff', to='DOSPORTAL.airports')), + ], + options={ + 'unique_together': {('flight_number', 'departure_time')}, + }, + ), + migrations.CreateModel( + name='measurement_campaign', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('name', models.CharField(blank=True, max_length=150, null=True, verbose_name='measurement name')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Organization', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('name', models.CharField(max_length=200)), + ('slug', models.SlugField(blank=True, max_length=255, unique=True)), + ('data_policy', models.CharField(choices=[('PR', 'Private'), ('PU', 'Public'), ('NV', 'Non-public')], default='PU', max_length=2)), + ('can_users_change_policy', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('website', models.URLField(blank=True, null=True)), + ('contact_email', models.EmailField(blank=True, max_length=200, null=True)), + ('description', models.TextField(blank=True, null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Trajectory', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('name', models.CharField(max_length=80)), + ('description', models.TextField(blank=True, null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='TrajectoryPoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('datetime', models.DateTimeField(blank=True, null=True, verbose_name='Point timestamp')), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, geography=True, null=True, srid=4326)), + ('trajectory', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='points', to='DOSPORTAL.trajectory')), + ], + ), + migrations.CreateModel( + name='record', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('log_file', models.FileField(blank=True, upload_to=DOSPORTAL.models.record.user_directory_path, verbose_name='File log')), + ('log_original_filename', models.CharField()), ('time_start', models.DateTimeField(null=True, verbose_name='Measurement beginning time')), - ('time_end', models.DateTimeField(null=True, verbose_name='Measurement beginning time')), + ('record_duration', models.DurationField(help_text='Duration of record', null=True, verbose_name='Record duration')), + ('record_type', models.CharField(choices=[('U', 'Unknown'), ('S', 'Spectral measurements'), ('E', 'Event measurements'), ('L', 'Location')], default='U', help_text='Type of log file', verbose_name='Certain record type, enum')), + ('metadata', models.JSONField(help_text='record metadata, used for advanced data processing and maintaining', null=True, verbose_name='record_metadata')), + ('data_policy', models.CharField(choices=[('PR', 'Private'), ('PU', 'Public'), ('NV', 'Non-public')], default='PU', max_length=2)), + ('belongs', models.ForeignKey(help_text='Organization, which owns this record', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='records_owning', to='DOSPORTAL.organization')), + ('detector', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='records', to='DOSPORTAL.detector')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(default='default_user_profileimage.jpg', upload_to='profile_pics')), + ('web', models.URLField(blank=True, null=True)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='OrganizationUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user_type', models.CharField(choices=[('ME', 'Member'), ('AD', 'Admin'), ('OW', 'Owner')], default='ME', max_length=2)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_organizations', to='DOSPORTAL.organization')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organization_users', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'organization')}, + }, + ), + migrations.AddField( + model_name='organization', + name='users', + field=models.ManyToManyField(related_name='organizations', through='DOSPORTAL.OrganizationUser', to=settings.AUTH_USER_MODEL), + ), + migrations.CreateModel( + name='MeasurementDataFlight', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('flight', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='measurements', to='DOSPORTAL.flight')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='measurement', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('time_start', models.DateTimeField(blank=True, null=True, verbose_name='Measurement beginning time')), + ('time_end', models.DateTimeField(blank=True, null=True, verbose_name='Measurement beginning time')), ('time_created', models.DateTimeField(auto_now_add=True, verbose_name='Time of creation')), ('name', models.CharField(max_length=150, verbose_name='measurement name')), - ('description', models.CharField(max_length=500, verbose_name='Measurement description')), - ('measurement_type', models.CharField(verbose_name='Certain measurement type, enum')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('description', martor.models.MartorField(blank=True, verbose_name='Measurement description')), + ('public', models.BooleanField(default=True, verbose_name='Will be data publicly available')), + ('measurement_type', models.CharField(choices=[('D', 'Debug measurement'), ('S', 'Static measurement'), ('M', 'Mobile measurement (ground)'), ('C', 'Civil airborne measurement'), ('A', 'Special airborne measurement')], default='S', help_text='Type of measurement', verbose_name='Certain measurement type, enum')), + ('base_location_lat', models.FloatField(blank=True, default=None, null=True)), + ('base_location_lon', models.FloatField(blank=True, default=None, null=True)), + ('base_location_alt', models.FloatField(blank=True, default=None, null=True)), + ('location_file', models.FileField(blank=True, upload_to=DOSPORTAL.models.measurement.user_directory_path, verbose_name='File log')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='measurements', to=settings.AUTH_USER_MODEL)), + ('campaings', models.ManyToManyField(blank=True, related_name='Campaigns', to='DOSPORTAL.measurement_campaign')), + ('flight', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='measurement', to='DOSPORTAL.flight', verbose_name='Reference na objekt s informacemi o letu')), ], options={ 'abstract': False, }, ), migrations.CreateModel( - name='record', + name='DetectorType', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('log_file', models.FileField(upload_to=DOSPORTAL.models.record.user_directory_path, verbose_name='File log')), - ('time_start', models.DateTimeField(null=True, verbose_name='Measurement beginning time')), - ('time_end', models.DateTimeField(null=True, verbose_name='Measurement beginning time')), - ('detector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detector')), - ('measurement', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.measurement')), + ('name', models.CharField(max_length=80)), + ('manufacturer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectormanufacturer')), ], options={ 'abstract': False, }, ), + migrations.CreateModel( + name='DetectorLogbook', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('text', models.TextField(help_text='Detailed description of activity made on the detector.', verbose_name='Logbook text')), + ('public', models.BooleanField(default=True, help_text='Private logbook will be visible for maintainers of detector and for dosportal admins.', verbose_name='Wish to be visible to everyone?')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('detector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='logbook', to='DOSPORTAL.detector')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='detector', + name='access', + field=models.ManyToManyField(blank=True, related_name='detector_access', to='DOSPORTAL.organization'), + ), + migrations.AddField( + model_name='detector', + name='calib', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='detectors', to='DOSPORTAL.detectorcalib'), + ), + migrations.AddField( + model_name='detector', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='detectors', to='DOSPORTAL.organization'), + ), migrations.AddField( model_name='detector', - name='manufacturer', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectormanufacturer'), + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectortype'), ), ] diff --git a/DOSPORTAL/migrations/0002_detectormanufacturer_name_detectormanufacturer_url.py b/DOSPORTAL/migrations/0002_detectormanufacturer_name_detectormanufacturer_url.py deleted file mode 100644 index 7f781af..0000000 --- a/DOSPORTAL/migrations/0002_detectormanufacturer_name_detectormanufacturer_url.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 08:25 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='detectormanufacturer', - name='name', - field=models.CharField(default=1, max_length=80), - preserve_default=False, - ), - migrations.AddField( - model_name='detectormanufacturer', - name='url', - field=models.URLField(default=1), - preserve_default=False, - ), - ] diff --git a/DOSPORTAL/migrations/0002_spectrumdata.py b/DOSPORTAL/migrations/0002_spectrumdata.py new file mode 100644 index 0000000..992d619 --- /dev/null +++ b/DOSPORTAL/migrations/0002_spectrumdata.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.11 on 2024-03-27 10:17 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('DOSPORTAL', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='SpectrumData', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('time_difference', models.DurationField(help_text='Time difference from the start of the measurement', null=True, verbose_name='Time difference')), + ('location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='spectrum_data', to='DOSPORTAL.trajectorypoint')), + ('record', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='spectrum_data', to='DOSPORTAL.record')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/DOSPORTAL/migrations/0003_remove_detector_manufacturer_detectortype_and_more.py b/DOSPORTAL/migrations/0003_remove_detector_manufacturer_detectortype_and_more.py deleted file mode 100644 index 6c9fcf1..0000000 --- a/DOSPORTAL/migrations/0003_remove_detector_manufacturer_detectortype_and_more.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 08:28 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0002_detectormanufacturer_name_detectormanufacturer_url'), - ] - - operations = [ - migrations.RemoveField( - model_name='detector', - name='manufacturer', - ), - migrations.CreateModel( - name='DetectorType', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('name', models.CharField(max_length=80)), - ('manufacturer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectormanufacturer')), - ], - options={ - 'abstract': False, - }, - ), - migrations.AddField( - model_name='detector', - name='type', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectortype'), - preserve_default=False, - ), - ] diff --git a/DOSPORTAL/migrations/0003_spectrumdata_spectrum.py b/DOSPORTAL/migrations/0003_spectrumdata_spectrum.py new file mode 100644 index 0000000..e414b98 --- /dev/null +++ b/DOSPORTAL/migrations/0003_spectrumdata_spectrum.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.11 on 2024-03-27 10:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('DOSPORTAL', '0002_spectrumdata'), + ] + + operations = [ + migrations.AddField( + model_name='spectrumdata', + name='spectrum', + field=models.JSONField(default=[], help_text='Energy spectrum data as an array of integers', verbose_name='Spectrum data'), + preserve_default=False, + ), + ] diff --git a/DOSPORTAL/migrations/0004_alter_measurement_measurement_type.py b/DOSPORTAL/migrations/0004_alter_measurement_measurement_type.py deleted file mode 100644 index f9af038..0000000 --- a/DOSPORTAL/migrations/0004_alter_measurement_measurement_type.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 09:21 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0003_remove_detector_manufacturer_detectortype_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='measurement', - name='measurement_type', - field=models.CharField(blank=True, choices=[('D', 'Debug measurement'), ('S', 'Static measurement'), ('M', 'Mobile measurement (ground)'), ('C', 'Civil airborne measurement'), ('A', 'Special airborne measurement')], default='S', help_text='Type of measurement', verbose_name='Certain measurement type, enum'), - ), - ] diff --git a/DOSPORTAL/migrations/0004_spectrumdata_metadata_spectrumdata_particles_and_more.py b/DOSPORTAL/migrations/0004_spectrumdata_metadata_spectrumdata_particles_and_more.py new file mode 100644 index 0000000..0b8c546 --- /dev/null +++ b/DOSPORTAL/migrations/0004_spectrumdata_metadata_spectrumdata_particles_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.11 on 2024-03-27 10:52 + +import django.contrib.postgres.fields.hstore +from django.db import migrations, models +import django.db.models.deletion +from django.contrib.postgres.operations import HStoreExtension + +class Migration(migrations.Migration): + + dependencies = [ + ('DOSPORTAL', '0003_spectrumdata_spectrum'), + ] + + operations = [ + HStoreExtension(), + migrations.AddField( + model_name='spectrumdata', + name='metadata', + field=django.contrib.postgres.fields.hstore.HStoreField(blank=True, help_text='Additional metadata for the spectrum data', null=True, verbose_name='Metadata'), + ), + migrations.AddField( + model_name='spectrumdata', + name='particles', + field=models.ImageField(blank=True, help_text='Particles detected in the spectrum', null=True, upload_to='', verbose_name='Particles'), + ), + migrations.AlterField( + model_name='spectrumdata', + name='record', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='spectrum_data', to='DOSPORTAL.record', verbose_name='Record'), + ), + ] diff --git a/DOSPORTAL/migrations/0005_alter_spectrumdata_metadata_and_more.py b/DOSPORTAL/migrations/0005_alter_spectrumdata_metadata_and_more.py new file mode 100644 index 0000000..fef434a --- /dev/null +++ b/DOSPORTAL/migrations/0005_alter_spectrumdata_metadata_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.11 on 2024-03-27 10:54 + +import django.contrib.postgres.fields.hstore +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('DOSPORTAL', '0004_spectrumdata_metadata_spectrumdata_particles_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='spectrumdata', + name='metadata', + field=django.contrib.postgres.fields.hstore.HStoreField(blank=True, default={}, help_text='Additional metadata for the spectrum data', null=True, verbose_name='Metadata'), + ), + migrations.AlterField( + model_name='spectrumdata', + name='particles', + field=models.IntegerField(blank=True, help_text='Particles detected in the spectrum', null=True, verbose_name='Particles'), + ), + ] diff --git a/DOSPORTAL/migrations/0005_measurement_public.py b/DOSPORTAL/migrations/0005_measurement_public.py deleted file mode 100644 index a304cbb..0000000 --- a/DOSPORTAL/migrations/0005_measurement_public.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 16:21 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0004_alter_measurement_measurement_type'), - ] - - operations = [ - migrations.AddField( - model_name='measurement', - name='public', - field=models.BooleanField(default=True, verbose_name='Will be data publicly available'), - ), - ] diff --git a/DOSPORTAL/migrations/0006_measurement_base_location_alt_and_more.py b/DOSPORTAL/migrations/0006_measurement_base_location_alt_and_more.py deleted file mode 100644 index 4aae482..0000000 --- a/DOSPORTAL/migrations/0006_measurement_base_location_alt_and_more.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 17:18 - -import DOSPORTAL.models -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0005_measurement_public'), - ] - - operations = [ - migrations.AddField( - model_name='measurement', - name='base_location_alt', - field=models.FloatField(default=1), - preserve_default=False, - ), - migrations.AddField( - model_name='measurement', - name='base_location_lat', - field=models.FloatField(default=1), - preserve_default=False, - ), - migrations.AddField( - model_name='measurement', - name='base_location_lon', - field=models.FloatField(default=1), - preserve_default=False, - ), - migrations.AddField( - model_name='measurement', - name='location_file', - field=models.FileField(default=1, upload_to=DOSPORTAL.models.measurement.user_directory_path, verbose_name='File log'), - preserve_default=False, - ), - ] diff --git a/DOSPORTAL/migrations/0006_spectrumdata_integration_alter_spectrumdata_spectrum.py b/DOSPORTAL/migrations/0006_spectrumdata_integration_alter_spectrumdata_spectrum.py new file mode 100644 index 0000000..8789e3c --- /dev/null +++ b/DOSPORTAL/migrations/0006_spectrumdata_integration_alter_spectrumdata_spectrum.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.11 on 2024-03-27 11:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('DOSPORTAL', '0005_alter_spectrumdata_metadata_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='spectrumdata', + name='integration', + field=models.FloatField(blank=True, help_text='Duration of last exposition', null=True, verbose_name='Integration time'), + ), + migrations.AlterField( + model_name='spectrumdata', + name='spectrum', + field=models.JSONField(default=[], help_text='Energy spectrum data as an array of integers', verbose_name='Spectrum data'), + ), + ] diff --git a/DOSPORTAL/migrations/0007_alter_record_detector.py b/DOSPORTAL/migrations/0007_alter_record_detector.py deleted file mode 100644 index 7ee01ca..0000000 --- a/DOSPORTAL/migrations/0007_alter_record_detector.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 19:41 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0006_measurement_base_location_alt_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='record', - name='detector', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detector'), - ), - ] diff --git a/DOSPORTAL/migrations/0007_record_author.py b/DOSPORTAL/migrations/0007_record_author.py new file mode 100644 index 0000000..15dd3dd --- /dev/null +++ b/DOSPORTAL/migrations/0007_record_author.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.11 on 2024-03-27 12:55 + +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), + ('DOSPORTAL', '0006_spectrumdata_integration_alter_spectrumdata_spectrum'), + ] + + operations = [ + migrations.AddField( + model_name='record', + name='author', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/DOSPORTAL/migrations/0008_record_log_filename_alter_record_measurement.py b/DOSPORTAL/migrations/0008_record_log_filename_alter_record_measurement.py deleted file mode 100644 index 4b5bbaa..0000000 --- a/DOSPORTAL/migrations/0008_record_log_filename_alter_record_measurement.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 20:43 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0007_alter_record_detector'), - ] - - operations = [ - migrations.AddField( - model_name='record', - name='log_filename', - field=models.CharField(default=1), - preserve_default=False, - ), - migrations.AlterField( - model_name='record', - name='measurement', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='records', to='DOSPORTAL.measurement'), - ), - ] diff --git a/DOSPORTAL/migrations/0009_alter_measurement_base_location_alt_and_more.py b/DOSPORTAL/migrations/0009_alter_measurement_base_location_alt_and_more.py deleted file mode 100644 index 3215575..0000000 --- a/DOSPORTAL/migrations/0009_alter_measurement_base_location_alt_and_more.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 21:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0008_record_log_filename_alter_record_measurement'), - ] - - operations = [ - migrations.AlterField( - model_name='measurement', - name='base_location_alt', - field=models.FloatField(default=None, null=True), - ), - migrations.AlterField( - model_name='measurement', - name='base_location_lat', - field=models.FloatField(default=None, null=True), - ), - migrations.AlterField( - model_name='measurement', - name='base_location_lon', - field=models.FloatField(default=None, null=True), - ), - ] diff --git a/DOSPORTAL/migrations/0010_airports_flight_measurementdataflight_record_flight.py b/DOSPORTAL/migrations/0010_airports_flight_measurementdataflight_record_flight.py deleted file mode 100644 index ce02b69..0000000 --- a/DOSPORTAL/migrations/0010_airports_flight_measurementdataflight_record_flight.py +++ /dev/null @@ -1,57 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 22:21 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0009_alter_measurement_base_location_alt_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Airports', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('name', models.CharField()), - ('code_iata', models.CharField(null=True, unique=True)), - ('code_icao', models.CharField(null=True, unique=True)), - ('lat', models.FloatField(null=True)), - ('lon', models.FloatField(null=True)), - ('alt', models.FloatField(null=True)), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='Flight', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('callsign', models.CharField()), - ('land', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='landing', to='DOSPORTAL.airports')), - ('takeoff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='takeoff', to='DOSPORTAL.airports')), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='MeasurementDataFlight', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('flight', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='measurements', to='DOSPORTAL.flight')), - ], - options={ - 'abstract': False, - }, - ), - migrations.AddField( - model_name='record', - name='flight', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='record', to='DOSPORTAL.flight'), - ), - ] diff --git a/DOSPORTAL/migrations/0011_flight_trajectory_file.py b/DOSPORTAL/migrations/0011_flight_trajectory_file.py deleted file mode 100644 index 46e8477..0000000 --- a/DOSPORTAL/migrations/0011_flight_trajectory_file.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-05 22:37 - -import DOSPORTAL.models -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0010_airports_flight_measurementdataflight_record_flight'), - ] - - operations = [ - migrations.AddField( - model_name='flight', - name='trajectory_file', - field=models.FileField(default=1, upload_to=DOSPORTAL.models.Flight.user_directory_path, verbose_name='Trajectory log'), - preserve_default=False, - ), - ] diff --git a/DOSPORTAL/migrations/0012_alter_record_flight.py b/DOSPORTAL/migrations/0012_alter_record_flight.py deleted file mode 100644 index b697f2c..0000000 --- a/DOSPORTAL/migrations/0012_alter_record_flight.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2.1 on 2023-06-06 00:42 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0011_flight_trajectory_file'), - ] - - operations = [ - migrations.AlterField( - model_name='record', - name='flight', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='record', to='DOSPORTAL.flight', verbose_name='Reference na objekt s informacemi o letu'), - ), - ] diff --git a/DOSPORTAL/migrations/0013_rename_callsign_flight_flight_number_and_more.py b/DOSPORTAL/migrations/0013_rename_callsign_flight_flight_number_and_more.py deleted file mode 100644 index f64fc1c..0000000 --- a/DOSPORTAL/migrations/0013_rename_callsign_flight_flight_number_and_more.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-21 23:29 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0012_alter_record_flight'), - ] - - operations = [ - migrations.RenameField( - model_name='flight', - old_name='callsign', - new_name='flight_number', - ), - migrations.AddField( - model_name='flight', - name='departure_time', - field=models.DateTimeField(null=True, verbose_name='Scheduled departure time'), - ), - migrations.AlterUniqueTogether( - name='flight', - unique_together={('flight_number', 'departure_time')}, - ), - ] diff --git a/DOSPORTAL/migrations/0014_remove_record_flight_measurement_flight.py b/DOSPORTAL/migrations/0014_remove_record_flight_measurement_flight.py deleted file mode 100644 index 3d4a604..0000000 --- a/DOSPORTAL/migrations/0014_remove_record_flight_measurement_flight.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-22 12:31 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0013_rename_callsign_flight_flight_number_and_more'), - ] - - operations = [ - migrations.RemoveField( - model_name='record', - name='flight', - ), - migrations.AddField( - model_name='measurement', - name='flight', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='record', to='DOSPORTAL.flight', verbose_name='Reference na objekt s informacemi o letu'), - ), - ] diff --git a/DOSPORTAL/migrations/0015_alter_measurement_flight.py b/DOSPORTAL/migrations/0015_alter_measurement_flight.py deleted file mode 100644 index 93e9e60..0000000 --- a/DOSPORTAL/migrations/0015_alter_measurement_flight.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-22 12:34 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0014_remove_record_flight_measurement_flight'), - ] - - operations = [ - migrations.AlterField( - model_name='measurement', - name='flight', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='record', to='DOSPORTAL.flight', verbose_name='Reference na objekt s informacemi o letu'), - ), - ] diff --git a/DOSPORTAL/migrations/0016_record_record_type_and_more.py b/DOSPORTAL/migrations/0016_record_record_type_and_more.py deleted file mode 100644 index c48d8ed..0000000 --- a/DOSPORTAL/migrations/0016_record_record_type_and_more.py +++ /dev/null @@ -1,60 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-22 14:54 - -import DOSPORTAL.models -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0015_alter_measurement_flight'), - ] - - operations = [ - migrations.AddField( - model_name='record', - name='record_type', - field=models.CharField(choices=[('S', 'Spectral measurements'), ('L', 'Location (GPX, FR24, NMEA)')], default='S', help_text='Type of log file', verbose_name='Certain record type, enum'), - ), - migrations.AlterField( - model_name='measurement', - name='base_location_alt', - field=models.FloatField(blank=True, default=None, null=True), - ), - migrations.AlterField( - model_name='measurement', - name='base_location_lat', - field=models.FloatField(blank=True, default=None, null=True), - ), - migrations.AlterField( - model_name='measurement', - name='base_location_lon', - field=models.FloatField(blank=True, default=None, null=True), - ), - migrations.AlterField( - model_name='measurement', - name='location_file', - field=models.FileField(blank=True, upload_to=DOSPORTAL.models.measurement.user_directory_path, verbose_name='File log'), - ), - migrations.AlterField( - model_name='measurement', - name='measurement_type', - field=models.CharField(choices=[('D', 'Debug measurement'), ('S', 'Static measurement'), ('M', 'Mobile measurement (ground)'), ('C', 'Civil airborne measurement'), ('A', 'Special airborne measurement')], default='S', help_text='Type of measurement', verbose_name='Certain measurement type, enum'), - ), - migrations.AlterField( - model_name='measurement', - name='time_end', - field=models.DateTimeField(blank=True, null=True, verbose_name='Measurement beginning time'), - ), - migrations.AlterField( - model_name='measurement', - name='time_start', - field=models.DateTimeField(blank=True, null=True, verbose_name='Measurement beginning time'), - ), - migrations.AlterField( - model_name='record', - name='detector', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detector'), - ), - ] diff --git a/DOSPORTAL/migrations/0017_airports_municipality_airports_web_and_more.py b/DOSPORTAL/migrations/0017_airports_municipality_airports_web_and_more.py deleted file mode 100644 index 20bfc0a..0000000 --- a/DOSPORTAL/migrations/0017_airports_municipality_airports_web_and_more.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-23 17:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0016_record_record_type_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='airports', - name='municipality', - field=models.CharField(null=True), - ), - migrations.AddField( - model_name='airports', - name='web', - field=models.CharField(null=True), - ), - migrations.AlterField( - model_name='record', - name='record_type', - field=models.CharField(choices=[('S', 'Spectral measurements'), ('L', 'Location')], default='S', help_text='Type of log file', verbose_name='Certain record type, enum'), - ), - ] diff --git a/DOSPORTAL/migrations/0018_detectorcalib.py b/DOSPORTAL/migrations/0018_detectorcalib.py deleted file mode 100644 index d7c200f..0000000 --- a/DOSPORTAL/migrations/0018_detectorcalib.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-23 23:36 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('DOSPORTAL', '0017_airports_municipality_airports_web_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='DetectorCalib', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('name', models.CharField(verbose_name='Calibration name')), - ('description', models.TextField(verbose_name='Description of calibration status')), - ('date', models.DateTimeField()), - ('cabib', models.CharField(verbose_name='Slozky kalibrace, json')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - options={ - 'abstract': False, - }, - ), - ] diff --git a/DOSPORTAL/migrations/0019_remove_detectorcalib_author.py b/DOSPORTAL/migrations/0019_remove_detectorcalib_author.py deleted file mode 100644 index 2129f94..0000000 --- a/DOSPORTAL/migrations/0019_remove_detectorcalib_author.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-23 23:41 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0018_detectorcalib'), - ] - - operations = [ - migrations.RemoveField( - model_name='detectorcalib', - name='author', - ), - ] diff --git a/DOSPORTAL/migrations/0020_detector_calib.py b/DOSPORTAL/migrations/0020_detector_calib.py deleted file mode 100644 index 1bf15b7..0000000 --- a/DOSPORTAL/migrations/0020_detector_calib.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-23 23:42 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0019_remove_detectorcalib_author'), - ] - - operations = [ - migrations.AddField( - model_name='detector', - name='calib', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectorcalib'), - ), - ] diff --git a/DOSPORTAL/migrations/0021_measurement_campaign_alter_detector_calib_and_more.py b/DOSPORTAL/migrations/0021_measurement_campaign_alter_detector_calib_and_more.py deleted file mode 100644 index e60fc49..0000000 --- a/DOSPORTAL/migrations/0021_measurement_campaign_alter_detector_calib_and_more.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-24 01:20 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0020_detector_calib'), - ] - - operations = [ - migrations.CreateModel( - name='measurement_campaign', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('name', models.CharField(max_length=150, verbose_name='measurement name')), - ], - options={ - 'abstract': False, - }, - ), - migrations.AlterField( - model_name='detector', - name='calib', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detectorcalib'), - ), - migrations.AddField( - model_name='measurement', - name='compaings', - field=models.ManyToManyField(related_name='Campaigns', to='DOSPORTAL.measurement_campaign'), - ), - ] diff --git a/DOSPORTAL/migrations/0022_alter_measurement_campaign_name.py b/DOSPORTAL/migrations/0022_alter_measurement_campaign_name.py deleted file mode 100644 index 5b79449..0000000 --- a/DOSPORTAL/migrations/0022_alter_measurement_campaign_name.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-24 01:28 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0021_measurement_campaign_alter_detector_calib_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='measurement_campaign', - name='name', - field=models.CharField(blank=True, max_length=150, null=True, verbose_name='measurement name'), - ), - ] diff --git a/DOSPORTAL/migrations/0023_alter_detectorcalib_cabib.py b/DOSPORTAL/migrations/0023_alter_detectorcalib_cabib.py deleted file mode 100644 index 9ec59c8..0000000 --- a/DOSPORTAL/migrations/0023_alter_detectorcalib_cabib.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-24 12:07 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0022_alter_measurement_campaign_name'), - ] - - operations = [ - migrations.AlterField( - model_name='detectorcalib', - name='cabib', - field=models.JSONField(verbose_name='Slozky kalibrace, json'), - ), - ] diff --git a/DOSPORTAL/migrations/0024_rename_compaings_measurement_campaings.py b/DOSPORTAL/migrations/0024_rename_compaings_measurement_campaings.py deleted file mode 100644 index 8d2fb96..0000000 --- a/DOSPORTAL/migrations/0024_rename_compaings_measurement_campaings.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-24 20:26 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0023_alter_detectorcalib_cabib'), - ] - - operations = [ - migrations.RenameField( - model_name='measurement', - old_name='compaings', - new_name='campaings', - ), - ] diff --git a/DOSPORTAL/migrations/0025_detectorlogblock.py b/DOSPORTAL/migrations/0025_detectorlogblock.py deleted file mode 100644 index 5203e3a..0000000 --- a/DOSPORTAL/migrations/0025_detectorlogblock.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-24 22:29 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('DOSPORTAL', '0024_rename_compaings_measurement_campaings'), - ] - - operations = [ - migrations.CreateModel( - name='DetectorLogblock', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('created', models.DateTimeField(auto_now_add=True)), - ('text', models.TextField(verbose_name='Description zásahu')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('detector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.detector')), - ], - options={ - 'abstract': False, - }, - ), - ] diff --git a/DOSPORTAL/migrations/0026_detectorlogbook_delete_detectorlogblock.py b/DOSPORTAL/migrations/0026_detectorlogbook_delete_detectorlogblock.py deleted file mode 100644 index e2efa16..0000000 --- a/DOSPORTAL/migrations/0026_detectorlogbook_delete_detectorlogblock.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-24 22:33 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('DOSPORTAL', '0025_detectorlogblock'), - ] - - operations = [ - migrations.CreateModel( - name='DetectorLogbook', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('created', models.DateTimeField(auto_now_add=True)), - ('text', models.TextField(verbose_name='Description zásahu')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('detector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='logbook', to='DOSPORTAL.detector')), - ], - options={ - 'abstract': False, - }, - ), - migrations.DeleteModel( - name='DetectorLogblock', - ), - ] diff --git a/DOSPORTAL/migrations/0027_alter_measurement_description.py b/DOSPORTAL/migrations/0027_alter_measurement_description.py deleted file mode 100644 index eb4a8bd..0000000 --- a/DOSPORTAL/migrations/0027_alter_measurement_description.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.2.2 on 2023-06-25 07:55 - -from django.db import migrations -import martor.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0026_detectorlogbook_delete_detectorlogblock'), - ] - - operations = [ - migrations.AlterField( - model_name='measurement', - name='description', - field=martor.models.MartorField(verbose_name='Measurement description'), - ), - ] diff --git a/DOSPORTAL/migrations/0028_alter_detector_calib_alter_measurement_author_and_more.py b/DOSPORTAL/migrations/0028_alter_detector_calib_alter_measurement_author_and_more.py deleted file mode 100644 index 83bbfc6..0000000 --- a/DOSPORTAL/migrations/0028_alter_detector_calib_alter_measurement_author_and_more.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by Django 4.2.3 on 2023-07-04 15:48 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import martor.models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('DOSPORTAL', '0027_alter_measurement_description'), - ] - - operations = [ - migrations.AlterField( - model_name='detector', - name='calib', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='detectors', to='DOSPORTAL.detectorcalib'), - ), - migrations.AlterField( - model_name='measurement', - name='author', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='measurements', to=settings.AUTH_USER_MODEL), - ), - migrations.AlterField( - model_name='measurement', - name='campaings', - field=models.ManyToManyField(blank=True, related_name='Campaigns', to='DOSPORTAL.measurement_campaign'), - ), - migrations.AlterField( - model_name='measurement', - name='description', - field=martor.models.MartorField(blank=True, verbose_name='Measurement description'), - ), - migrations.AlterField( - model_name='record', - name='detector', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='records', to='DOSPORTAL.detector'), - ), - ] diff --git a/DOSPORTAL/migrations/0029_carimodel_flight_cari.py b/DOSPORTAL/migrations/0029_carimodel_flight_cari.py deleted file mode 100644 index 71bdc0f..0000000 --- a/DOSPORTAL/migrations/0029_carimodel_flight_cari.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 4.2.3 on 2023-07-05 21:02 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0028_alter_detector_calib_alter_measurement_author_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='CARImodel', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('data', models.JSONField()), - ], - options={ - 'abstract': False, - }, - ), - migrations.AddField( - model_name='flight', - name='cari', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.carimodel'), - ), - ] diff --git a/DOSPORTAL/migrations/0030_alter_flight_cari_alter_measurement_flight.py b/DOSPORTAL/migrations/0030_alter_flight_cari_alter_measurement_flight.py deleted file mode 100644 index 87b98db..0000000 --- a/DOSPORTAL/migrations/0030_alter_flight_cari_alter_measurement_flight.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-03 10:54 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0029_carimodel_flight_cari'), - ] - - operations = [ - migrations.AlterField( - model_name='flight', - name='cari', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='DOSPORTAL.carimodel'), - ), - migrations.AlterField( - model_name='measurement', - name='flight', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='measurement', to='DOSPORTAL.flight', verbose_name='Reference na objekt s informacemi o letu'), - ), - ] diff --git a/DOSPORTAL/migrations/0031_detectorlogbook_public.py b/DOSPORTAL/migrations/0031_detectorlogbook_public.py deleted file mode 100644 index c934c87..0000000 --- a/DOSPORTAL/migrations/0031_detectorlogbook_public.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-03 16:09 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0030_alter_flight_cari_alter_measurement_flight'), - ] - - operations = [ - migrations.AddField( - model_name='detectorlogbook', - name='public', - field=models.BooleanField(default=True), - ), - ] diff --git a/DOSPORTAL/migrations/0032_detector_data_alter_detectorlogbook_public_and_more.py b/DOSPORTAL/migrations/0032_detector_data_alter_detectorlogbook_public_and_more.py deleted file mode 100644 index 4169079..0000000 --- a/DOSPORTAL/migrations/0032_detector_data_alter_detectorlogbook_public_and_more.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-03 17:21 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0031_detectorlogbook_public'), - ] - - operations = [ - migrations.AddField( - model_name='detector', - name='data', - field=models.JSONField(default={}, help_text='Detector metadata, used for advanced data processing and maintaining', verbose_name='Detector data'), - preserve_default=False, - ), - migrations.AlterField( - model_name='detectorlogbook', - name='public', - field=models.BooleanField(default=True, help_text='Private logbook will be visible for maintainers of detector and for dosportal admins.', verbose_name='Wish to be visible to everyone?'), - ), - migrations.AlterField( - model_name='detectorlogbook', - name='text', - field=models.TextField(help_text='Detailed description of activity made on the detector.', verbose_name='Logbook text'), - ), - ] diff --git a/DOSPORTAL/migrations/0033_detector_manufactured_date.py b/DOSPORTAL/migrations/0033_detector_manufactured_date.py deleted file mode 100644 index 5c68e33..0000000 --- a/DOSPORTAL/migrations/0033_detector_manufactured_date.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-03 17:23 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0032_detector_data_alter_detectorlogbook_public_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='detector', - name='manufactured_date', - field=models.DateField(blank=True, help_text='Date when detector was manufactured', null=True, verbose_name='Manufactured date'), - ), - ] diff --git a/DOSPORTAL/migrations/0034_record_metadata_alter_detector_data.py b/DOSPORTAL/migrations/0034_record_metadata_alter_detector_data.py deleted file mode 100644 index 787539a..0000000 --- a/DOSPORTAL/migrations/0034_record_metadata_alter_detector_data.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-03 20:03 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0033_detector_manufactured_date'), - ] - - operations = [ - migrations.AddField( - model_name='record', - name='metadata', - field=models.JSONField(help_text='record metadata, used for advanced data processing and maintaining', null=True, verbose_name='record_metadata'), - ), - migrations.AlterField( - model_name='detector', - name='data', - field=models.JSONField(help_text='Detector metadata, used for advanced data processing and maintaining', verbose_name='Detector metadata'), - ), - ] diff --git a/DOSPORTAL/migrations/0035_remove_record_time_end_record_record_duration.py b/DOSPORTAL/migrations/0035_remove_record_time_end_record_record_duration.py deleted file mode 100644 index f4f5a1f..0000000 --- a/DOSPORTAL/migrations/0035_remove_record_time_end_record_record_duration.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-03 21:17 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('DOSPORTAL', '0034_record_metadata_alter_detector_data'), - ] - - operations = [ - migrations.RemoveField( - model_name='record', - name='time_end', - ), - migrations.AddField( - model_name='record', - name='record_duration', - field=models.DurationField(help_text='Duration of record', null=True, verbose_name='Record duration'), - ), - ] diff --git a/DOSPORTAL/models.py b/DOSPORTAL/models.py index 81252f2..8acdf4d 100644 --- a/DOSPORTAL/models.py +++ b/DOSPORTAL/models.py @@ -1,3 +1,4 @@ +from typing import Iterable from django.db import models import uuid from django.utils.translation import gettext as _ @@ -7,8 +8,14 @@ from martor.models import MartorField from django_q.tasks import async_task from django.utils.text import slugify +from django.contrib.auth.models import User +from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation +from django.contrib.contenttypes.models import ContentType +from django.db import models +from django.contrib.gis.db import models as geomodels + -from .tasks import process_flight_entry +from .tasks import process_flight_entry, process_record_entry def get_enum_dsc(enum, t): @@ -31,7 +38,17 @@ def get_admin_url(self): class Meta: abstract = True + + +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + image = models.ImageField(default='default_user_profileimage.jpg', upload_to='profile_pics') + web = models.URLField(max_length=200, null=True, blank=True) + + + def __str__(self): + return f'{self.user.username} Profile' #show how we want it to be displayed class Organization(UUIDMixin): @@ -44,7 +61,7 @@ class Organization(UUIDMixin): name = models.CharField(max_length=200) users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='organizations', through='OrganizationUser') slug = models.SlugField(max_length=255, unique=True, blank=True) - data_policy = models.CharField(max_length=2, choices=DATA_POLICY_CHOICES, default='PR') + data_policy = models.CharField(max_length=2, choices=DATA_POLICY_CHOICES, default='PU') can_users_change_policy = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -52,6 +69,7 @@ class Organization(UUIDMixin): contact_email = models.EmailField(max_length=200, null=True, blank=True) description = models.TextField(null=True, blank=True) + def save(self, *args, **kwargs): # Aktualizace slug pole na základě názvu, pokud není zadáno if not self.slug: @@ -66,6 +84,10 @@ def get_members(self): def get_admin_url(self): return reverse("admin:%s_%s_change" % (self._meta.app_label, self._meta.model_name), args=(self.id,)) + + + def get_absolute_url(self): + return reverse('organization-detail', args=[str(self.id)]) @@ -87,6 +109,8 @@ class Meta: def __str__(self): return f'{self.user.username}: {self.get_user_type_display()} of {self.organization.name}' + + class CARImodel(UUIDMixin): data = models.JSONField() @@ -135,6 +159,7 @@ def user_directory_path(instance, filename): trajectory_file = models.FileField( verbose_name=_("Trajectory log"), upload_to=user_directory_path, + ) cari = models.ForeignKey( @@ -234,7 +259,6 @@ class DetectorCalib(UUIDMixin): - class Detector(UUIDMixin): sn = models.CharField( @@ -270,8 +294,25 @@ class Detector(UUIDMixin): help_text="Detector metadata, used for advanced data processing and maintaining" ) + owner = models.ForeignKey( + Organization, + on_delete=models.DO_NOTHING, + related_name="detectors", + blank=True, + null=True + ) + + access = models.ManyToManyField( + Organization, + related_name="detector_access", + blank=True + + ) + def __str__(self) -> str: return "Detector {} ({}), SN:{}".format(self.name, self.type.manufacturer.name, self.sn) + + class DetectorLogbook(UUIDMixin): @@ -411,11 +452,11 @@ class record(UUIDMixin): Obsahuje jednotlivý log z detektoru """ - measurement = models.ForeignKey( - measurement, - on_delete=models.CASCADE, - related_name='records' - ) + # measurement = models.ForeignKey( + # measurement, + # on_delete=models.CASCADE, + # related_name='records' + # ) detector = models.ForeignKey( Detector, @@ -426,14 +467,17 @@ class record(UUIDMixin): ) def user_directory_path(instance, filename): - return "data/user_records/log_{1}".format(instance.measurement.author.pk, instance.pk) + print("USER FILENAME", filename) + return "user_records/record_{0}".format(instance.pk) log_file = models.FileField( verbose_name=_("File log"), upload_to=user_directory_path, + blank=True ) - log_filename = models.CharField( + + log_original_filename = models.CharField( ) @@ -471,6 +515,26 @@ def user_directory_path(instance, filename): null=True ) + belongs = models.ForeignKey( + Organization, + on_delete=models.DO_NOTHING, + null=True, + related_name="records_owning", + help_text=_("Organization, which owns this record") + ) + + data_policy = models.CharField(max_length=2, choices= Organization.DATA_POLICY_CHOICES, default='PU') + + author = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + null=True, + blank = True, + ) + + def save(self, *args, **kwargs): + super(record, self).save(*args, **kwargs) + def __str__(self) -> str: return "record ({}, {}, start {}, {})".format( get_enum_dsc(self.RECORD_TYPES, self.record_type), self.id, self.time_start, 0) @@ -479,3 +543,108 @@ def description(self) -> str: + + + +class Trajectory(UUIDMixin): + name = models.CharField( + max_length = 80 + ) + + description = models.TextField( + null=True, + blank=True + ) + + def __str__(self) -> str: + return "Trajectory: {}".format(self.name) + + + +class TrajectoryPoint(models.Model): + datetime = models.DateTimeField( + null=True, + blank=True, + verbose_name = _("Point timestamp"), + ) + + location = geomodels.PointField( + null=True, + blank=True, + geography=True, + ) + + trajectory = models.ForeignKey( + Trajectory, + on_delete=models.CASCADE, + related_name="points" + ) + + def __str__(self) -> str: + return "Trajectory point: {}".format(self.trajectory) + +from django.contrib.postgres.fields import ArrayField, HStoreField + +class SpectrumData(UUIDMixin): + """ + Model to store energy spectrum data + """ + record = models.ForeignKey( + 'record', + on_delete=models.CASCADE, + related_name='spectrum_data', + verbose_name=_("Record") + ) + + spectrum = models.JSONField( + _("Spectrum data"), + help_text=_("Energy spectrum data as an array of integers"), + default=list(), + ) + + integration = models.FloatField( + _("Integration time"), + help_text = _("Duration of last exposition"), + null = True, + blank = True + ) + + particles = models.IntegerField( + _("Particles"), + help_text=_("Particles detected in the spectrum"), + null=True, + blank=True, + ) + + metadata = HStoreField( + _("Metadata"), + help_text=_("Additional metadata for the spectrum data"), + null=True, + blank=True, + default=dict() + ) + + location = models.ForeignKey( + TrajectoryPoint, + on_delete=models.CASCADE, + related_name='spectrum_data', + null=True, + blank=True + ) + time_difference = models.DurationField( + verbose_name=_("Time difference"), + help_text=_("Time difference from the start of the measurement"), + null=True + ) + # Add any other fields that you think might be useful + + def __str__(self) -> str: + return f"Spectrum data {self.record.id}" + + def save(self, *args, **kwargs): + self.particles = sum(self.spectrum) + + self.metadata['particles'] = self.particles + + super(SpectrumData, self).save(*args, **kwargs) + diff --git a/DOSPORTAL/tasks.py b/DOSPORTAL/tasks.py index b3aba41..4d1c021 100644 --- a/DOSPORTAL/tasks.py +++ b/DOSPORTAL/tasks.py @@ -53,3 +53,12 @@ def process_flight_entry(Flight): +def process_record_entry(Record): + print(Record) + print(".................") + print(".....") + + Record.record_duration = 10 + Record.save() + + return "OK" diff --git a/DOSPORTAL/urls.py b/DOSPORTAL/urls.py index b3ad721..cee1467 100644 --- a/DOSPORTAL/urls.py +++ b/DOSPORTAL/urls.py @@ -16,13 +16,17 @@ """ from django.contrib import admin from django.urls import path, include +from django.conf.urls.static import static +from django.conf import settings from . import views from django.views.generic.base import TemplateView + import uuid from .users.views_users import user_profile +from .users import urls as user_urls from .views import MeasurementsListView, MeasurementDetailView, MeasurementNewView, MeasurementNewView, MeasurementDataView, measuredDataGet, measuredSpectraGet, MeasurementRecordNewView -from .views_detectors import DetectorView, DetectorOverview, DetectorNewLogbookRecord +from .views_detectors import DetectorView, DetectorEditView,DetectorOverview, DetectorNewLogbookRecord from .views_flights import FlightView from .views_record import RecordsListView, RecordView, RecordNewView, GetSpectrum, GetEvolution @@ -36,8 +40,12 @@ #path(r'accounts/', include('organizations.urls')), #path(r'invitations/', include(invitation_backend().get_urls())), - path('user/', user_profile, name='profile'), - path('user/', user_profile, name='user_profile'), + #path('user/', user_profile, name='profile'), + #path('user/', user_profile, name='user_profile'), + + path('user/', include('DOSPORTAL.users.urls')), + path('organization/', include('DOSPORTAL.PART_organizations.urls')), + #path('account/', include('DOSPORTAL.users.urls')), path("measurements/", MeasurementsListView.as_view(), name="measurements"), path("measurement/new/", MeasurementNewView, name='measurement-new'), @@ -61,7 +69,9 @@ path('flight//', FlightView, name='flight-detail'), path('detector//new_logbook_record', DetectorNewLogbookRecord), + path('detector/new/', DetectorEditView, name="detector-new"), path('detectors/', DetectorOverview.as_view(), name="detector-overview"), + path('detector//edit/', DetectorEditView, name="detector-edit"), path('detector//', DetectorView, name="detector-view"), path("select2/", include("django_select2.urls")), @@ -75,3 +85,6 @@ path('api/', include('api.urls')), path('', TemplateView.as_view(template_name='home.html'), name='home'), ] + + +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/DOSPORTAL/users/urls.py b/DOSPORTAL/users/urls.py new file mode 100644 index 0000000..4e33bf9 --- /dev/null +++ b/DOSPORTAL/users/urls.py @@ -0,0 +1,14 @@ +from django.contrib import admin +from django.urls import path, include +from django.views.generic.base import TemplateView +import uuid + +from . import views_users + +urlpatterns = [ + + + path(r'', views_users.user_profile, name='user_profile'), + path(r'', views_users.user_profile, name='profile'), + +] \ No newline at end of file diff --git a/DOSPORTAL/views_detectors.py b/DOSPORTAL/views_detectors.py index 81627f1..ca7d8d6 100644 --- a/DOSPORTAL/views_detectors.py +++ b/DOSPORTAL/views_detectors.py @@ -3,7 +3,7 @@ from django.views import generic from .models import (DetectorManufacturer, measurement, record, Detector, DetectorType, DetectorLogbook) -from .forms import DetectorLogblogForm +from .forms import DetectorLogblogForm, DetectorEditForm from django.shortcuts import get_object_or_404, redirect, render @@ -21,6 +21,16 @@ def DetectorView(request, pk): #return HttpResponse(a) return render(request, 'detectors/detectors_detail.html', context={'detector': detector, 'DetectorLogblogForm': DetectorLogblogForm}) +def DetectorEditView(request, pk=None): + detectorEditForm = DetectorEditForm( instance=Detector.objects.get(pk=pk) if pk else None) + + if request.method == 'POST': + detectorEditForm = DetectorEditForm(request.POST) + if detectorEditForm.is_valid(): + detectorEditForm.save() + return redirect('detector-view', pk=detectorEditForm.instance.pk) + + return render(request, 'detectors/detector_edit.html', context={'detectorEditForm': detectorEditForm}) class DetectorOverview(generic.ListView): diff --git a/DOSPORTAL/views_record.py b/DOSPORTAL/views_record.py index 95bfe95..4d89f29 100644 --- a/DOSPORTAL/views_record.py +++ b/DOSPORTAL/views_record.py @@ -2,9 +2,10 @@ from django.http import HttpResponse, JsonResponse from django.views import generic from .models import (DetectorManufacturer, measurement, record, - record, Detector, DetectorType, DetectorLogbook) + Detector, DetectorType, DetectorLogbook) from .forms import DetectorLogblogForm - +import os +from django.conf import settings from django.shortcuts import get_object_or_404, redirect, render from DOSPORTAL import models @@ -20,48 +21,117 @@ class RecordsListView(generic.ListView): model = record context_object_name = 'records_list' - queryset = record.objects.filter() + queryset = record.objects.all() template_name = 'records/records_list.html' - def get_context_data(self, **kwargs): - context = super(RecordsListView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) return context +def handle_uploaded_file(f, file): + print("Ukládám soubor " + file) + with open(file, "wb+") as destination: + for chunk in f.chunks(): + destination.write(chunk) + print("ukladani souboru hotovo") + + +def obtain_parameters_from_log(file): + + f = open(file) + line_1 = f.readline().rstrip().split(',') + record_metadata = {} + record_metadata['detector'] = dict(zip(['DET', 'detector_type', 'firmware_build', 'channels', 'firmware_commit', 'firmware_origin', 'detector_sn'], line_1)) + + time_start = 0 + stop_stop = 0 + while True: + line = f.readline() + if line.startswith('$HIST'): + line = line.rstrip().split(',') + time_start = float(line[2]) + break + i = -1 + flen = len(f.readlines()) + while True: + f.seek(flen+i) + line = f.readline() + if line.startswith('$HIST'): + line = line.rstrip().split(',') + time_stop = float(line[2]) + count = int(line[1]) + break + i -= 1 + + record_metadata['record'] = {} + record_metadata['record'] = { + 'duration': time_stop - time_start, + 'count': count + } + + + f.close() + return record_metadata + def RecordNewView(request): if request.method == "POST": print("POST... s formulářem :) ") form = RecordForm(request.POST, request.FILES) - #print(form) - + if form.is_valid(): data = form.save(commit=False) data.author = request.user data.log_file = request.FILES['log_file'] + + #request.FILES['log_file'].save() + + data.log_original_filename = data.log_file.name + + print("LOG FILE PATH", data.log_file.path) + print("LOG FILE NAME", data.log_file.name) + + # Get the original file name + original_file_name = data.log_file.name + + # Create a new file name + new_file_name = "new_" + original_file_name + + new_file_name = data.pk + new_file_path = os.path.join(settings.MEDIA_ROOT, 'user_records', str(data.pk) ) + + # Update the file name and path + #data.log_file.name = new_file_name + #data.log_file.path = new_file_path + + # handle_uploaded_file(request.FILES['log_file'], new_file_path) + # try: + # metadata = obtain_parameters_from_log(new_file_path) + # except: + # metadata = None - #data.log_filename = request.FILES['log_file'].name.split("/")[-1] - handle_uploaded_file(request.FILES['log_file'], data.log_file.name) - metadata = obtain_parameters_from_log(data.log_file.path) - print("Medatada z logu") - print(metadata) - if metadata: - detector_pk = Detector.objects.get(sn=metadata['detector']['detector_sn']) - if detector_pk: - data.detector = detector_pk - data.metadata = metadata - data.record_duration = timedelta(seconds = metadata['record']['duration']) - #data.measurement = measurement.objects.get(pk=pk) + # #handle_uploaded_file(request.FILES['log_file'], data.log_file.path) + # #metadata = obtain_parameters_from_log(data.log_file.path) + # print("Medatada z logu") + # print(metadata) + # if metadata: + # detector_pk = Detector.objects.get(sn=metadata['detector']['detector_sn']) + # if detector_pk: + # data.detector = detector_pk + # data.metadata = metadata + # data.record_duration = timedelta(seconds = metadata['record']['duration']) + # #data.measurement = measurement.objects.get(pk=pk) pk = data.pk print(data) data.save() + + return redirect("record-view", pk=pk) else: print("Form není validni") print(form.errors) - - return redirect("record-detail", pk=pk) + return render(request, 'records/record_new.html', {'form': form}) else: form = RecordForm() diff --git a/Dockerfile b/Dockerfile index 9a91fbc..c25238c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 RUN apt-get update -RUN apt-get install -y python3 net-tools python3-pip libpq-dev redis +RUN apt-get install -y python3 net-tools python3-pip libpq-dev redis binutils libproj-dev gdal-bin WORKDIR /DOSPORTAL COPY requirements.txt /DOSPORTAL/ diff --git a/data/media/default_user_profileimage.jpg b/data/media/default_user_profileimage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..efcbaf8d0fbc3acbadb47a6920a1482d0aab5eb9 GIT binary patch literal 7852 zcmeHLc{r49+rP(Hvo#DNHH<73P4);=c1j*9B9Ube zQkIOAY?YlEq^a578PD@ROV9Tl&+~rA@g3hEZ`a)C%ynJod7t<7`(4+4U%z`e{hVQ7 zwY{~SH2?wu0EqhmI3vJrD=gX{0PO5G0m1+P@BvaFFweDO=v4ldUo~!1GTfF@+KBz6em|z6fI~1Y4Wh(+OL1II_eS=VuNrg!VIqyXre^bqKXU1)^=^!clwU_U!YG3-UGcgCot9Ot8k-;Lu=Hq_+|_ z_-IIkG1e5mlH8bE=XE3CN-H6eL8kBn4nHYbV8T&KdRz3iY}Mj|i`Id2bArLLMtLRB+?tJ6%wKH?+lix2;XpY zXe1gFqQuMS?SqMmG=+1ozcMfsm {(%CXXN7}*heo3P|00y<`6ZNhmhn$$Eb8b1 zOLQ$OFp0|L3DUdgl4?HGf92my=|}m&zz+s~Fz|zc9}N6p;J=T7-xM4wge%)(xcZFq z7O()oe0;ovTll$$fUtl7Kfk~#At6Cwu~lMXqN_wj#U-Rxi%UQxL`7H2u7*fMWn^T; zB<0q~Lf1$^WuUwyATakFegP2y0THOUs5taLE}SL+A`GwrHW&m4_#hxK1jK0pU|cCH z09q+Lk;*F|KJFL=g@i>`iE;yKRs(z>Fqn@Y%o{b=8_)Fv{15>tW$m4U(oWt&@Gz)O z(%EamD&`d=8RstQ23?=}a%H!$30WNcw+Wo=_?XTNvfeizpR zZtlK*DF1*!^pS|jsOT7MY+TCm6DL#C(lfGi&YjQAyKwPRQStQ~H*b~PzEfFMT~k~4 zpuXWrb4x3^t^MhpO~DYEi5j5Uj9P=`i+MR1b}~r#r^&t zaY4Aa`1tw3{6aijAifwLa0tJEvbLbqPA4JnFlo3>k}%Z#?6nG#h>ET=RmLa0YnAK< zy%AL!584W{e+Df1e}(K@IwX3afEk z&MXC*JPD$aPJ#O1N;JY zx{caaCFV?eT|~n0!_^JvU%Vh+rlvf3^~PPSkb<+#_j}3ijh=YBw^z=;GuFuq#EfQL zGl^i>(EBjb*m1WU=Y|fgnj)0e(PDKo56HOiW7AHZmi(Yj4KRfbPoNAbBy4)2LeCrZ zO2fdz?W*e@1s%jN7A4v_0BvBwXgqf+AQ!#f&EsRfwdV79J5%(zp9BU~JbE7?qqkH) zHlKE=U#C`mu_%lK@HvYg`|@O-u3^(QbbO&nZ$2$9x55`9UrrMhw^s9-`{dC;_#z)P zZm$7ewpqq-faF&C_BL0821IMH5*D`a+;N2$>FDY<-@)Ebwt}HX?;m$)l)ZYP?ovUi z?l@$#`%ztQB%`FI{Lp}XW$Px$nf58$!#1HoUwz7M5q*(w+sOFJXrg%DWy3Txn8&UL zMst;2ODs~awuJ+f<}{j3FNK6Y1F;00Jo28DW#r4#dxlNb$!3t=;@5gw_DCK1yp!hJ z0te$tZ?~gNk~iNg5LPZ+LbX9_;L;N5I5GY_3 zs`i-#jSL+(4kpPenC!ZHba@6C_=F|ZvX2i+oo)**tY87-w9MR4g0@vqYicX?-Y zz!f<|E+L+XZH4{>vii=vV)3N4Y?Y@Yn1N)*lX+zZEF%&<0trY7!=!f+h5L9*u`DHM z0#8@JU#gbH2w-k}ko8P=>gKz%lbSk~HlvCJaw4)wL8B;f)!$h&tuvFYLUm2kyU?WL zHTgyMj-Y?#F%M|~-pc>C`Z-nrPaC*w}Yx+Tq)ZEsgj_CJE-nF^Tc-phCjYJFL z@TmgP4>Y+pj5Pgypy&ZQ#@3+A-iB}LW9@xOR`}^q{Cg;fq5nNif6*5DNMXuGEQeoq z>Uo5u<=NDr6{!`My+m8wPXXdczsYjSs%BGOy1j%kQCAy<4wU3BeUtBa* zTj@49(9vx>XzQI{xJXh=Nj8#UE++IBROY22{pK?$2{7X6Afkk)?#pY_nncx)jd4=j zq;8rwEN@c^Mr{B;3H)xs%Iw+-NI3!$pIL$&fV7oXeCx)W>A0vDCyUVntP{`uH_nC>yTQ*3lU!W*x2lxrQ}J!{bd~vLSh}2? z!mY$8Q9`Oh^+jJa6n~`WY6DGrYv3Zgd3IfPA`%){R>_9rNva$m5W&Aoxkv91f}ESN zNBz}jsCZqiZ^5&p3=ItVQNUhSW}^vOr#gZOqZLKV$>6POwI7kJsrhhbOa1*m0g;UQX1D`oZ5v2_+!RN4HnPj_=pF=}8l zZ6XUV$21BhljA5u9H4xjDYe)FTZ7T#0P;BJss`#%67((=?VKXMeAhUM@K{X!p`xy2 z1EAbCG*pFWN(YSy&CG@cm8xA<&wS(xlDO2_DC?-)hE)dpVNFgdU%|&UmKLs35KOvB zceSkOS~|8iUe~_jMDXmRocdt?xKl7#H8|o7&3xS5g*YKoyEMa z2bzv_J!ipi$E|*_%`wxHPrckswThn|?rL#^8AcDguXF!04g6#v#c)uz;dS+OmO*`? z#6U*Iz?5jeOHgcaz8a&_l5~zGd^_+TDw{DgO`I<^plM#janwr@o7~g<&C(_?_hWi& zfxHORS4*W}u0;Lzga)|kzV2uY83V?x=_1zP!ba~Qnhh-1W#L01A62TuSYIV8lYAeZm1ylN}~+(1RFp1@gI0dd4k4iE&( z99r!cQHFD*Im}@C2KDW{Q`ju){Yd+Tw-2Ar&#gap`$PTJPIottD(x@oIZjSH1fV~g zg0XtKK1SSwb<6fOBC?e5bruy$C4RcDunZGmzr({!__%krAJc`VQUs~hvY#0uYxk=* zMYYv#ZVoJze1$(bM0JN{uobc1wA7Q2kYk&z$X~r(d*%w*f+vb$$M-KINb~f~c_dic zf<5^Y6fLH zO`9d0l_ChE;liGo9dtB}I5w2UeLfKs97pkr(|eE9b=oEa_HW(Dj^9dDIw3;qj7$$? z+uaXpGuuW=H<|2Dc?1dD!k8C7^bA*=vuFp7`0#X2aBWu8u*v|LP?Kz+&_B5x098cn3ZL3u9Ddch9vJ0z(>B`v1++9mEOuZ3w)!3)v$be=x zMDQ9We?PHdY(w$brudyGC0O@588Qw=uNxtr#!FOV6zF@FJSPUOoB2p5ZP>C6d)?#e z{jBpUyqG<_N$bm^wvmj-PnlRmYE~aw-@WVYZNdh)*qP#o>l33kBpOo| z&oXx5@Dw~6pQ$i(I*Jm=?q%=KIz4mad{NFvbK;J0TgLO}gVRefY*7owjz+>rnHW>4 zM}4Egy{w=E{rxW*j1FQ6C1{y#wgd4w{1_!=AEhqmh+)p4hf(fmtb&{3 zXMf*pyzWnbvGBiBmb_7TUB^?cU>Q1Sm<$dxEI$tKaqp4dSC>WLI~KEw6hB~;ZdRl` z>2>-1XCzY^?0VUbRmWCLyKub0u&=v>tr{f%jkRVYQv>`B^!u0An+=+2?M*u6B%y22 zDGl(~ORQ@NkRwRG1U>r0rf=sYMJEjxY(nO=#}7(3h}cw-oro~^#b@l}9N;LX{~)QL z<`V&9%6vI8FMq(&r<^8!cW1wv-NMb?1Ot=o9qpU!lrqbac`yiaID4pCE=6C&w`