From e704d6ae7f09f673c02874609a048b29eb23fed8 Mon Sep 17 00:00:00 2001
From: Stefano Alberto Russo <stefano.russo@gmail.com>
Date: Wed, 31 Mar 2021 00:17:46 +0200
Subject: [PATCH] Added support for custom texts. Refactored the home (main)
 page to support a custom text.

---
 .../webapp/code/rosetta/core_app/admin.py     |  3 ++-
 .../management/commands/core_app_populate.py  | 27 +++++++++++++++++--
 .../rosetta/core_app/migrations/0003_text.py  | 20 ++++++++++++++
 .../webapp/code/rosetta/core_app/models.py    | 11 ++++++++
 .../code/rosetta/core_app/templates/main.html | 23 +++++++++++++++-
 .../webapp/code/rosetta/core_app/views.py     | 10 ++++++-
 6 files changed, 89 insertions(+), 5 deletions(-)
 create mode 100644 services/webapp/code/rosetta/core_app/migrations/0003_text.py

diff --git a/services/webapp/code/rosetta/core_app/admin.py b/services/webapp/code/rosetta/core_app/admin.py
index 56b2fe7..db79005 100644
--- a/services/webapp/code/rosetta/core_app/admin.py
+++ b/services/webapp/code/rosetta/core_app/admin.py
@@ -1,6 +1,6 @@
 from django.contrib import admin
 
-from .models import Profile, LoginToken, Task, Container, Computing, ComputingSysConf, ComputingUserConf, KeyPair
+from .models import Profile, LoginToken, Task, Container, Computing, ComputingSysConf, ComputingUserConf, KeyPair, Text
 
 admin.site.register(Profile)
 admin.site.register(LoginToken)
@@ -10,3 +10,4 @@ admin.site.register(Computing)
 admin.site.register(ComputingSysConf)
 admin.site.register(ComputingUserConf)
 admin.site.register(KeyPair)
+admin.site.register(Text)
diff --git a/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py b/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
index 7e63802..8bcdfd0 100644
--- a/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
+++ b/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
@@ -1,6 +1,6 @@
 from django.core.management.base import BaseCommand
 from django.contrib.auth.models import User
-from ...models import Profile, Container, Computing, ComputingSysConf, ComputingUserConf, KeyPair
+from ...models import Profile, Container, Computing, ComputingSysConf, ComputingUserConf, KeyPair, Text
 
 class Command(BaseCommand):
     help = 'Adds the admin superuser with \'a\' password.'
@@ -38,7 +38,30 @@ class Command(BaseCommand):
                                 default = True,
                                 private_key_file = '/rosetta/.ssh/id_rsa',
                                 public_key_file = '/rosetta/.ssh/id_rsa.pub')
-            
+
+        # Default homepage text
+        default_home_text_content = '''
+<div class="span8 offset2" style="margin: 30px auto; max-width:800px">
+  Welcome to Rosetta!
+  <br/><br/>
+  This is the default home text loaded after populating the platform with the default/demo data.
+  To change it, head to the <a href="/admin">admin</a> page and edit the <code>Text</code> model.
+  <br/><br/>
+  The default installation provides a test user register with email <code>testuser@rosetta.platform</code>
+  and password <code>testpass</code>, which you can use to login on the menu on the right or using the link
+  below and give Rosetta a try immediately. If you run with the default docker-compose file (i.e. you just
+  run <code>rosetta/setup</code>), then you will also have a few demo computing resources you can play with
+  out-of-the-box, including a small Slurm cluster. Otherwise, you will need to setup your own computing
+  resources either platform-wide or as user.
+</div>
+'''
+        home_text = Text.objects.filter(id='home')
+        if home_text:
+            print('Not creating default home text as already present')
+        else:
+            print('Creating default home text...')
+            Text.objects.create(id='home', content=default_home_text_content)
+
 
         # Public containers
         public_containers = Container.objects.filter(user=None)
diff --git a/services/webapp/code/rosetta/core_app/migrations/0003_text.py b/services/webapp/code/rosetta/core_app/migrations/0003_text.py
new file mode 100644
index 0000000..b1fbd96
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0003_text.py
@@ -0,0 +1,20 @@
+# Generated by Django 2.2.1 on 2021-03-30 22:02
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0002_container_protocol'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Text',
+            fields=[
+                ('id', models.CharField(max_length=16, primary_key=True, serialize=False, verbose_name='Text id')),
+                ('content', models.TextField(blank=True, null=True, verbose_name='Text content')),
+            ],
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/models.py b/services/webapp/code/rosetta/core_app/models.py
index 9749a1a..a3dffde 100644
--- a/services/webapp/code/rosetta/core_app/models.py
+++ b/services/webapp/code/rosetta/core_app/models.py
@@ -378,7 +378,18 @@ class KeyPair(models.Model):
 
 
 
+#=========================
+#  Texts 
+#=========================
+
+class Text(models.Model):
+    '''A model to store some text contents for the platform, like the home page text'''
 
+    id = models.CharField('Text id', max_length=16, primary_key=True)
+    content = models.TextField('Text content', blank=True, null=True)
+
+    def __str__(self):
+        return str('Text with id "{}"'.format(self.id))
 
 
 
diff --git a/services/webapp/code/rosetta/core_app/templates/main.html b/services/webapp/code/rosetta/core_app/templates/main.html
index 47e41e0..6f9656e 100644
--- a/services/webapp/code/rosetta/core_app/templates/main.html
+++ b/services/webapp/code/rosetta/core_app/templates/main.html
@@ -10,9 +10,30 @@
                 <h2 style="margin-top:10px; margin-left:25px; margin-right:25px; font-weight:100; line-height: 30px;"><i>A container-centric Science Platform<br></i></h2>
             </div>
         </div>
+        
+        <div class="container">
+            <div class="dashboard">
+                {% if data.home_text %}
+                {{ data.home_text | safe }}
+                {% else %}
+                <div class="span8 offset2" style="margin: 30px auto; max-width:800px">
+                <br/>
+                Welcome to Rosetta!
+                <br/><br/>
+                This is an empty installation. To load some demo data, run <code>rosetta/populate</code>.
+                </div>
+                {% endif %}
+            </div>
+        </div>
+
         <div style="display:table-row">
             <div class="text-vertical-bottom">
-                <a href="https://github.com/sarusso/Rosetta" class="btn btn-dark btn-lg">Find Out More</a>
+                {% if user.is_authenticated %}
+                <a href="/tasks" class="btn btn-dark btn-lg">Tasks</a>
+                <a href="/containers" class="btn btn-dark btn-lg">Containers</a>
+                {% else %}
+                <a href="/login" class="btn btn-dark btn-lg">Log In</a>
+                {% endif %}
             </div>
         </div>
     </header>
diff --git a/services/webapp/code/rosetta/core_app/views.py b/services/webapp/code/rosetta/core_app/views.py
index 1939a4b..617dec5 100644
--- a/services/webapp/code/rosetta/core_app/views.py
+++ b/services/webapp/code/rosetta/core_app/views.py
@@ -8,7 +8,7 @@ from django.contrib.auth import authenticate, login, logout
 from django.http import HttpResponse, HttpResponseRedirect
 from django.contrib.auth.models import User
 from django.shortcuts import redirect
-from .models import Profile, LoginToken, Task, TaskStatuses, Container, Computing, KeyPair, ComputingSysConf, ComputingUserConf
+from .models import Profile, LoginToken, Task, TaskStatuses, Container, Computing, KeyPair, ComputingSysConf, ComputingUserConf, Text
 from .utils import send_email, format_exception, timezonize, os_shell, booleanize, debug_param, get_tunnel_host, random_username, setup_tunnel, finalize_user_creation
 from .decorators import public_view, private_view
 from .exceptions import ErrorMessage
@@ -190,6 +190,14 @@ def main_view(request):
 
     # Set data & render
     data = {}
+    
+    # Get homepage text if any
+    try:
+        text = Text.objects.get(id='home')
+        data['home_text'] = text.content
+    except Text.DoesNotExist:
+        pass
+
     return render(request, 'main.html', {'data': data})
 
 
-- 
GitLab