diff --git a/documentation/deployment_instructions.md b/documentation/deployment_instructions.md
index ddcdbdc..57f2058 100644
--- a/documentation/deployment_instructions.md
+++ b/documentation/deployment_instructions.md
@@ -35,7 +35,8 @@ The full list of settings is as follows:
| `POSTGRES_PASSWORD` | The password for Postgres access. This should be set to `'postgres'`. |
| `POSTGRES_PORT` | The port through which the Postgres is exposed. This should be set to `5432`. |
| `API_BASE_URL` | The URL and port by which the QCrBox tool manager can be accessed. If QCrBox is installed on the same machine as this setup, this should be set to `'http://host.docker.internal:11000'`. |
- | `API_VISUALISER_PORT` | The port through which the QCrBox_quality visualiser can be accessed. This should be set to `12008` in most cases. |
+ | `TRAEFIK_HTTP_PORT` | The port through which the Traefik router (which handles GUI routing) is exposed. For development, this should be set to `12345`. |
+ | `GUI_DOMAIN_PREFIX` | The prefix for GUI subdomains. This should be set to `.gui.` for default setups. |
| `MAX_LENGTH_API_LOG` | The maximum length of API output to be saved in the logs. As some API outputs can be quite long, this gives the option to truncate them in the logs, making the logs more unwieldy at the cost of losing some debug information. |
| `DJANGO_SUPERUSER_EMAIL` | The email address for the default admin account to be created for the web app. |
| `DJANGO_SUPERUSER_USERNAME` | The username for the default admin account to be created for the web app. |
diff --git a/environment.env.template b/environment.env.template
index 92bd476..6e31918 100644
--- a/environment.env.template
+++ b/environment.env.template
@@ -8,7 +8,8 @@ POSTGRES_PASSWORD='postgres'
POSTGRES_PORT=5432
API_BASE_URL='http://host.docker.internal:11000'
-API_VISUALISER_PORT='12008'
+TRAEFIK_HTTP_PORT='12345'
+GUI_DOMAIN_PREFIX='.gui.'
MAX_LENGTH_API_LOG=10000
diff --git a/qcrbox_frontend/core/settings.py b/qcrbox_frontend/core/settings.py
index f8692ec..c8977d6 100644
--- a/qcrbox_frontend/core/settings.py
+++ b/qcrbox_frontend/core/settings.py
@@ -211,7 +211,10 @@
# API settings
API_BASE_URL = os.environ.get('API_BASE_URL', 'http://127.0.0.1:11000')
-API_VISUALISER_PORT = os.environ.get('API_VISUALISER_PORT', '12008')
+
+# Traefik / GUI Routing settings
+TRAEFIK_HTTP_PORT = int(os.environ.get('TRAEFIK_HTTP_PORT', '12345') or 12345)
+GUI_DOMAIN_PREFIX = os.environ.get('GUI_DOMAIN_PREFIX', '.gui.')
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
diff --git a/qcrbox_frontend/qcrbox/forms.py b/qcrbox_frontend/qcrbox/forms.py
index 1510bec..ffe02a8 100644
--- a/qcrbox_frontend/qcrbox/forms.py
+++ b/qcrbox_frontend/qcrbox/forms.py
@@ -96,7 +96,14 @@ def __init__(self, *args, user, **kwargs):
objs = models.FileMetaData.objects # pylint: disable=no-member
qset = objs.filter(active=True).filter(group__in=permitted_groups)
- choices = [(f.pk, f.display_filename) for f in qset.all()]
+
+ # Filter to only retain the oldest file in each workflow tree, i.e. files which are
+ # not the output of any process
+ process_objs = models.ProcessStep.objects # pylint: disable=no-member
+ process_outfiles = process_objs.all().values_list('outfile', flat=True)
+ qset = qset.exclude(pk__in=process_outfiles)
+
+ choices = [(f.pk, str(f)) for f in qset.all()]
self.fields['file'].choices = choices
@@ -377,7 +384,7 @@ def __init__(self, *args, command, dataset, **kwargs):
else:
ext = 'cif'
- filepath = filepath + f'_{command.name}.{ext}'
+ filepath = filepath + f'.{ext}'
self.fields[param.name] = forms.CharField(
initial=filepath,
diff --git a/qcrbox_frontend/qcrbox/models.py b/qcrbox_frontend/qcrbox/models.py
index 580d99d..0077f55 100644
--- a/qcrbox_frontend/qcrbox/models.py
+++ b/qcrbox_frontend/qcrbox/models.py
@@ -55,8 +55,36 @@ class FileMetaData(models.Model):
def __str__(self):
'''Return the filename when an instance of this is parsed as string'''
+ max_len = 30
- return str(self.display_filename)
+ if len(self.display_filename) < max_len:
+ return str(self.display_filename)
+ return str(str(self.display_filename)[:max_len-3]+'...')
+
+ def get_newest_descendant(self):
+ '''Get the most recently created FileMetaData object which is a direct
+ descendant of this FileMetaData'''
+
+ related_pks = [self.pk]
+ last_gen_pks = [self.pk]
+
+ process_step_objs = ProcessStep.objects # pylint: disable=no-member
+
+ # Recursively scan all related process_steps for descendant pks
+ while len(last_gen_pks)>0:
+ gen_processes = process_step_objs.filter(infile__pk__in=last_gen_pks)
+ this_gen_pks = gen_processes.values_list('outfile__pk', flat=True)
+ related_pks += this_gen_pks
+ last_gen_pks = this_gen_pks
+
+ # Fetch the object corresponding to the most recently created related
+ # FileMetaData
+ file_metadata_objs = FileMetaData.objects # pylint: disable=no-member
+
+ related_objs = file_metadata_objs.filter(pk__in=related_pks)
+ recent_obj = related_objs.order_by('creation_time').last()
+
+ return recent_obj
class Application(models.Model):
diff --git a/qcrbox_frontend/qcrbox/templates/initial.html b/qcrbox_frontend/qcrbox/templates/initial.html
index 4b69c05..71c767f 100644
--- a/qcrbox_frontend/qcrbox/templates/initial.html
+++ b/qcrbox_frontend/qcrbox/templates/initial.html
@@ -18,7 +18,7 @@
{{ loadfile_form.as_p }}
@@ -28,7 +28,7 @@
{{ newfile_form.as_p }}
diff --git a/qcrbox_frontend/qcrbox/templates/workflow.html b/qcrbox_frontend/qcrbox/templates/workflow.html
index c1e37fd..35be572 100644
--- a/qcrbox_frontend/qcrbox/templates/workflow.html
+++ b/qcrbox_frontend/qcrbox/templates/workflow.html
@@ -23,8 +23,8 @@
-
| {% if prior_step.infile.active %} - + {% else %} {% endif %} | {% if prior_step.infile.active %} - {{prior_step.infile.display_filename}} + {{prior_step.infile}} {% else %} Deleted {% endif %} | {% if prior_step.infile.active %} - + -   - +   + -   - +   + - + {% endif %} | -  {{prior_step.application.name}} + {{prior_step.command.app.name}}: {{prior_step.command}} | {% endfor %} @@ -78,18 +78,18 @@- {{file.display_filename}} + {{file}} | - + -   - +   + -   - +   + - + |