From bdcce42e12408a3384f2cc89f527a487e043f9f2 Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 11:42:08 +0000 Subject: [PATCH 01/19] Update form title --- battDB/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/battDB/forms.py b/battDB/forms.py index 7f15e6bb..963a263a 100644 --- a/battDB/forms.py +++ b/battDB/forms.py @@ -382,7 +382,7 @@ def __init__(self, *args, **kwargs): self.helper.layout = Layout( Div( - Div(HTML(f"

{mode} file

")), + Div(HTML(f"

{mode} experiment data

")), Column("name", css_class="col-6"), Column("machine", css_class="col-6"), fieldset, From e719a330e1d6fa68b288d5e6d438e01b4dbe8aac Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 11:54:29 +0000 Subject: [PATCH 02/19] add new validators --- common/validators.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/common/validators.py b/common/validators.py index 604a962b..55c1bc54 100644 --- a/common/validators.py +++ b/common/validators.py @@ -43,3 +43,46 @@ def validate_pdf_file(file) -> None: raise ValidationError( "Unsupported file type and/or extension - must be a PDF file." ) + + +def validate_settings_file(file) -> None: + """ + Validates the settings file against the mime type and extension. + + Args: + file (FileField): File to validate. + + Raises: + ValidationError if validation not passed. + """ + allowed_mime_and_extensions = [ + ("text/plain", ".txt"), + ("text/plain", ".mps"), + ] + extension = os.path.splitext(file.name)[1] + file_mime_type = magic.from_buffer(file.read(1024), mime=True) + if (file_mime_type, extension) not in allowed_mime_and_extensions: + raise ValidationError( + "Unsupported file type and/or extension - must be a text file." + ) + + +def validate_binary_file(file) -> None: + """ + Validates the binary file against the mime type and extension. + + Args: + file (FileField): File to validate. + + Raises: + ValidationError if validation not passed. + """ + allowed_mime_and_extensions = [ + ("application/octet-stream", ".mpr"), + ] + extension = os.path.splitext(file.name)[1] + file_mime_type = magic.from_buffer(file.read(1024), mime=True) + if (file_mime_type, extension) not in allowed_mime_and_extensions: + raise ValidationError( + "Unsupported file type and/or extension - must be a binary file." + ) From 8cf01c12784de705466d1c399b9440bf85573544 Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 11:54:46 +0000 Subject: [PATCH 03/19] Update model with new fields --- battDB/models.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/battDB/models.py b/battDB/models.py index 2e43970e..a63e5281 100644 --- a/battDB/models.py +++ b/battDB/models.py @@ -11,7 +11,11 @@ import common.models as cm import dfndb.models as dfn -from common.validators import validate_pdf_file +from common.validators import ( + validate_binary_file, + validate_pdf_file, + validate_settings_file, +) from parsing_engines import available_parsing_engines, parse_data_file @@ -522,6 +526,24 @@ class ExperimentDataFile(cm.BaseModel): help_text="Test protocol used in this experiment", ) + settings_file = models.FileField( + upload_to="uploaded_files", + null=True, + blank=True, + validators=(validate_settings_file,), + verbose_name="Settings file", + help_text="Input settings file for the cycler used to produce this data", + ) + + binary_file = models.FileField( + upload_to="uploaded_files", + null=True, + blank=True, + validators=(validate_binary_file,), + verbose_name="Binary file", + help_text="Binary file version of this data output by the cycler", + ) + def num_cycles(self): return ( self.ranges.filter(step_action="cycle").count() From a0297508ca4dacc602527003f9a4cf68efa91baa Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 11:56:17 +0000 Subject: [PATCH 04/19] add migration --- ...experimentdatafile_binary_file_and_more.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 battDB/migrations/0031_experimentdatafile_binary_file_and_more.py diff --git a/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py b/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py new file mode 100644 index 00000000..4bd969e1 --- /dev/null +++ b/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.3 on 2022-11-21 11:55 + +from django.db import migrations, models + +import common.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('battDB', '0030_experiment_external_link_experiment_summary'), + ] + + operations = [ + migrations.AddField( + model_name='experimentdatafile', + name='binary_file', + field=models.FileField(blank=True, help_text='Binary file version of this data output by the cycler', null=True, upload_to='uploaded_files', validators=[common.validators.validate_binary_file], verbose_name='Binary file'), + ), + migrations.AddField( + model_name='experimentdatafile', + name='settings_file', + field=models.FileField(blank=True, help_text='Input settings file for the cycler used to produce this data', null=True, upload_to='uploaded_files', validators=[common.validators.validate_settings_file], verbose_name='Settings file'), + ), + ] From f4896d33719df511ef1d22ae83339df052157a57 Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 11:56:17 +0000 Subject: [PATCH 05/19] add migration --- ...experimentdatafile_binary_file_and_more.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py b/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py index 4bd969e1..97476f1f 100644 --- a/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py +++ b/battDB/migrations/0031_experimentdatafile_binary_file_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.3 on 2022-11-21 11:55 +# Generated by Django 4.1.3 on 2022-11-21 12:07 from django.db import migrations, models @@ -8,18 +8,32 @@ class Migration(migrations.Migration): dependencies = [ - ('battDB', '0030_experiment_external_link_experiment_summary'), + ("battDB", "0030_experiment_external_link_experiment_summary"), ] operations = [ migrations.AddField( - model_name='experimentdatafile', - name='binary_file', - field=models.FileField(blank=True, help_text='Binary file version of this data output by the cycler', null=True, upload_to='uploaded_files', validators=[common.validators.validate_binary_file], verbose_name='Binary file'), + model_name="experimentdatafile", + name="binary_file", + field=models.FileField( + blank=True, + help_text="Binary file version of this data output by the cycler (if available)", + null=True, + upload_to="uploaded_files", + validators=[common.validators.validate_binary_file], + verbose_name="Binary file", + ), ), migrations.AddField( - model_name='experimentdatafile', - name='settings_file', - field=models.FileField(blank=True, help_text='Input settings file for the cycler used to produce this data', null=True, upload_to='uploaded_files', validators=[common.validators.validate_settings_file], verbose_name='Settings file'), + model_name="experimentdatafile", + name="settings_file", + field=models.FileField( + blank=True, + help_text="Input settings file for the cycler used to produce this data (if available)", + null=True, + upload_to="uploaded_files", + validators=[common.validators.validate_settings_file], + verbose_name="Settings file", + ), ), ] From a552cff721095f38b88ccc8f76169c0adcb92fa3 Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 12:08:46 +0000 Subject: [PATCH 06/19] Update model help texts --- battDB/models.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/battDB/models.py b/battDB/models.py index a63e5281..3f92dade 100644 --- a/battDB/models.py +++ b/battDB/models.py @@ -532,7 +532,8 @@ class ExperimentDataFile(cm.BaseModel): blank=True, validators=(validate_settings_file,), verbose_name="Settings file", - help_text="Input settings file for the cycler used to produce this data", + help_text="Input settings file for the cycler used to produce this data (if " + "available)", ) binary_file = models.FileField( @@ -541,7 +542,8 @@ class ExperimentDataFile(cm.BaseModel): blank=True, validators=(validate_binary_file,), verbose_name="Binary file", - help_text="Binary file version of this data output by the cycler", + help_text="Binary file version of this data output by the cycler (if " + "available)", ) def num_cycles(self): From 3473164e78c93e067334a1ee2b6c0a7c71cf3a1c Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 12:09:10 +0000 Subject: [PATCH 07/19] Add settings and binary file fields --- battDB/forms.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/battDB/forms.py b/battDB/forms.py index 963a263a..8f2bf2da 100644 --- a/battDB/forms.py +++ b/battDB/forms.py @@ -326,6 +326,8 @@ class Meta: "name", "machine", "notes", + "settings_file", + "binary_file", ] help_texts = { "machine": mark_safe( @@ -386,6 +388,8 @@ def __init__(self, *args, **kwargs): Column("name", css_class="col-6"), Column("machine", css_class="col-6"), fieldset, + Column("settings_file", css_class="col-6"), + Column("binary_file", css_class="col-6"), Field("notes"), HTML("
"), Field("make_public"), From 42583f16e315c8109419471d54e88bdc3c95fad4 Mon Sep 17 00:00:00 2001 From: Daniel Davies Date: Mon, 21 Nov 2022 15:03:58 +0000 Subject: [PATCH 08/19] Add new buttons and views for download --- battDB/templates/experiment.html | 17 +++++++++++++---- battDB/urls.py | 12 ++++++++++++ battDB/views.py | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/battDB/templates/experiment.html b/battDB/templates/experiment.html index 9bd37bcd..d6a44f37 100644 --- a/battDB/templates/experiment.html +++ b/battDB/templates/experiment.html @@ -169,9 +169,9 @@
Measurement data: {{data_file.name}}