diff --git a/app/admin.py b/app/admin.py
index ef34ef52..be7e5e83 100644
--- a/app/admin.py
+++ b/app/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin
from guardian.admin import GuardedModelAdmin
from app.models import Preset
-from .models import Project, Task, ImageUpload
+from .models import Project, Task, ImageUpload, Setting, Theme
admin.site.register(Project, GuardedModelAdmin)
@@ -17,3 +17,12 @@ admin.site.register(ImageUpload, ImageUploadAdmin)
admin.site.register(Preset, admin.ModelAdmin)
+
+class SettingAdmin(admin.ModelAdmin):
+ def has_add_permission(self, request):
+ # if there's already an entry, do not allow adding
+ count = Setting.objects.all().count()
+ return count == 0
+
+admin.site.register(Setting, SettingAdmin)
+admin.site.register(Theme, admin.ModelAdmin)
\ No newline at end of file
diff --git a/app/boot.py b/app/boot.py
index 5b82a32a..63085ae5 100644
--- a/app/boot.py
+++ b/app/boot.py
@@ -1,15 +1,20 @@
+import os
+
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User, Group
from django.core.exceptions import ObjectDoesNotExist
+from django.core.files import File
from django.db.utils import ProgrammingError
from guardian.shortcuts import assign_perm
from app.models import Preset
+from app.models import Theme
from nodeodm.models import ProcessingNode
# noinspection PyUnresolvedReferences
+from webodm.settings import MEDIA_ROOT
from . import scheduler, signals
import logging
-from .models import Task
+from .models import Task, Setting
from webodm import settings
from webodm.wsgi import booted
@@ -65,6 +70,23 @@ def boot():
])
Preset.objects.get_or_create(name='Default', system=True, options=[{'name': 'dsm', 'value': True}])
+ # Add settings
+ Setting.objects.all().delete()
+ Theme.objects.all().delete()
+
+ default_theme, created = Theme.objects.get_or_create(name='Default')
+ if created:
+ logger.info("Created default theme")
+
+ if Setting.objects.all().count() == 0:
+ s = Setting.objects.create(
+ app_name='WebODM',
+ theme=default_theme)
+ default_logo = os.path.join('app', 'static', 'app', 'img', 'logo512.png')
+ s.app_logo.save(os.path.basename(default_logo), File(open(default_logo, 'rb')))
+
+ logger.info("Created settings")
+
# Unlock any Task that might have been locked
Task.objects.filter(processing_lock=True).update(processing_lock=False)
diff --git a/app/models/__init__.py b/app/models/__init__.py
index 184de3f5..7b510c73 100644
--- a/app/models/__init__.py
+++ b/app/models/__init__.py
@@ -2,3 +2,6 @@ from .image_upload import ImageUpload, image_directory_path
from .project import Project
from .task import Task, validate_task_options, gcp_directory_path
from .preset import Preset
+from .theme import Theme
+from .setting import Setting
+
diff --git a/app/models/setting.py b/app/models/setting.py
new file mode 100644
index 00000000..164cf4a2
--- /dev/null
+++ b/app/models/setting.py
@@ -0,0 +1,30 @@
+import logging
+
+from django.db import models
+from imagekit.models import ImageSpecField
+from imagekit.processors import ResizeToFit
+
+from .theme import Theme
+
+logger = logging.getLogger('app.logger')
+
+
+class Setting(models.Model):
+ app_name = models.CharField(max_length=255, blank=False, null=False, help_text="The name of your application")
+ app_logo = models.ImageField(upload_to="settings/", blank=False, null=False, help_text="A 512x512 logo of your application (.png or .jpeg)")
+ app_logo_36 = ImageSpecField(source='app_logo',
+ processors=[ResizeToFit(36, 36)],
+ format='PNG',
+ options={'quality': 90})
+ app_logo_favicon = ImageSpecField(source='app_logo',
+ processors=[ResizeToFit(48, 48)],
+ format='PNG',
+ options={'quality': 90})
+
+ organization_name = models.CharField(max_length=255, blank=True, null=True, help_text="The name of your organization")
+ organization_website = models.URLField(max_length=255, blank=True, null=True, help_text="The website URL of your organization")
+ theme = models.ForeignKey(Theme, blank=False, null=False, on_delete=models.DO_NOTHING,
+ help_text="Active theme")
+
+ def __str__(self):
+ return "Application"
\ No newline at end of file
diff --git a/app/models/theme.py b/app/models/theme.py
new file mode 100644
index 00000000..a315083e
--- /dev/null
+++ b/app/models/theme.py
@@ -0,0 +1,31 @@
+import logging
+
+from django.db import models
+from colorfield.fields import ColorField
+
+logger = logging.getLogger('app.logger')
+
+class Theme(models.Model):
+ name = models.CharField(max_length=255, blank=False, null=False, help_text="Name of theme")
+
+ # Similar to how discourse.org does it
+ primary = ColorField(default='#2c3e50', help_text="Most text, icons, and borders.")
+ secondary = ColorField(default='#ffffff', help_text="The main background color, and text color of some buttons.")
+ tertiary = ColorField(default='#18bc9c', help_text="Navigation links.")
+
+ button_primary = ColorField(default='#2c3e50', help_text="Primary button color.")
+ button_default = ColorField(default='#95a5a6', help_text="Default button color.")
+ button_danger = ColorField(default='#95a5a6', help_text="Delete button color.")
+
+ header_background = ColorField(default='#18bc9c', help_text="Background color of the site's header.")
+ header_primary = ColorField(default='#ffffff', help_text="Text and icons in the site's header.")
+ highlight = ColorField(default='#f7f7f7', help_text="The background color of panels.")
+
+ dialog_warning = ColorField(default='#f39c12', help_text="The border color of warning dialogs.")
+
+ failed = ColorField(default='#ffcbcb', help_text="The background color of failed notifications.")
+ success = ColorField(default='#cbffcd', help_text="The background color of success notifications.")
+
+ def __str__(self):
+ return self.name
+
diff --git a/app/static/app/android-chrome-192x192.png b/app/static/app/android-chrome-192x192.png
deleted file mode 100644
index c047cd29..00000000
Binary files a/app/static/app/android-chrome-192x192.png and /dev/null differ
diff --git a/app/static/app/android-chrome-512x512.png b/app/static/app/android-chrome-512x512.png
deleted file mode 100644
index 2b0ceb36..00000000
Binary files a/app/static/app/android-chrome-512x512.png and /dev/null differ
diff --git a/app/static/app/apple-touch-icon.png b/app/static/app/apple-touch-icon.png
deleted file mode 100644
index 00f374c7..00000000
Binary files a/app/static/app/apple-touch-icon.png and /dev/null differ
diff --git a/app/static/app/browserconfig.xml b/app/static/app/browserconfig.xml
deleted file mode 100644
index 658b5609..00000000
--- a/app/static/app/browserconfig.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-