From 29c233a44abd5aa5022cb33d968b80d4b85346c1 Mon Sep 17 00:00:00 2001 From: Marc Date: Fri, 10 Oct 2014 17:17:20 +0000 Subject: [PATCH] Added saas icons --- TODO.md | 2 + orchestra/apps/orchestration/admin.py | 14 +- orchestra/apps/orchestration/models.py | 12 +- orchestra/apps/orchestration/settings.py | 4 + orchestra/apps/saas/services/dokuwiki.py | 19 + orchestra/apps/saas/services/drupal.py | 19 + orchestra/apps/saas/services/moodle.py | 19 + orchestra/apps/saas/services/wordpress.py | 20 + orchestra/apps/saas/settings.py | 4 + .../apps/saas/static/saas/icons/Dokuwiki.svg | 553 ++++++++++++++++++ .../apps/saas/static/saas/icons/Drupal.svg | 1 + .../apps/saas/static/saas/icons/Moodle.svg | 233 ++++++++ .../apps/saas/static/saas/icons/WordPress.svg | 68 +++ .../apps/saas/static/saas/icons/gitlab.png | Bin 0 -> 32119 bytes .../webapps/tests/functional_tests/tests.py | 16 +- .../websites/tests/functional_tests/tests.py | 10 +- 16 files changed, 966 insertions(+), 28 deletions(-) create mode 100644 orchestra/apps/saas/services/dokuwiki.py create mode 100644 orchestra/apps/saas/services/drupal.py create mode 100644 orchestra/apps/saas/services/moodle.py create mode 100644 orchestra/apps/saas/services/wordpress.py create mode 100644 orchestra/apps/saas/static/saas/icons/Dokuwiki.svg create mode 100644 orchestra/apps/saas/static/saas/icons/Drupal.svg create mode 100644 orchestra/apps/saas/static/saas/icons/Moodle.svg create mode 100644 orchestra/apps/saas/static/saas/icons/WordPress.svg create mode 100644 orchestra/apps/saas/static/saas/icons/gitlab.png diff --git a/TODO.md b/TODO.md index 216a5e82..2557c795 100644 --- a/TODO.md +++ b/TODO.md @@ -138,3 +138,5 @@ Remember that, as always with QuerySets, any subsequent chained methods which im * Move MU webapps to SaaS? * DN: Transaction atomicity and backend failure + +* SaaS Icons diff --git a/orchestra/apps/orchestration/admin.py b/orchestra/apps/orchestration/admin.py index ae932b0d..fdbbffb6 100644 --- a/orchestra/apps/orchestration/admin.py +++ b/orchestra/apps/orchestration/admin.py @@ -46,8 +46,8 @@ class RouteAdmin(admin.ModelAdmin): class BackendOperationInline(admin.TabularInline): model = BackendOperation - fields = ('action', 'content_object_link') - readonly_fields = ('action', 'content_object_link') + fields = ('action', 'instance_link') + readonly_fields = ('action', 'instance_link') extra = 0 can_delete = False @@ -56,22 +56,22 @@ class BackendOperationInline(admin.TabularInline): 'all': ('orchestra/css/hide-inline-id.css',) } - def content_object_link(self, operation): + def instance_link(self, operation): try: - return admin_link('content_object')(self, operation) + return admin_link('instance')(self, operation) except: return _("deleted {0} {1}").format( escape(operation.content_type), escape(operation.object_id) ) - content_object_link.allow_tags = True - content_object_link.short_description = _("Content_object") + instance_link.allow_tags = True + instance_link.short_description = _("Instance") def has_add_permission(self, *args, **kwargs): return False def get_queryset(self, request): queryset = super(BackendOperationInline, self).get_queryset(request) - return queryset.prefetch_related('content_object') + return queryset.prefetch_related('instance') def display_mono(field): diff --git a/orchestra/apps/orchestration/models.py b/orchestra/apps/orchestration/models.py index 8ef143a9..826b795f 100644 --- a/orchestra/apps/orchestration/models.py +++ b/orchestra/apps/orchestration/models.py @@ -102,23 +102,19 @@ class BackendOperation(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') + instance = generic.GenericForeignKey('content_type', 'object_id') class Meta: verbose_name = _("Operation") verbose_name_plural = _("Operations") - def __init__(self, *args, **kwargs): - self.instance = kwargs.pop('instance', None) - super(BackendOperation, self).__init__(*args, **kwargs) - def __unicode__(self): - return '%s.%s(%s)' % (self.backend, self.action, self.instance or self.content_object) + return '%s.%s(%s)' % (self.backend, self.action, self.instance) def __hash__(self): """ set() """ backend = getattr(self, 'backend', self.backend) - return hash(backend) + hash(self.instance or self.content_object) + hash(self.action) + return hash(backend) + hash(self.instance) + hash(self.action) def __eq__(self, operation): """ set() """ @@ -126,7 +122,7 @@ class BackendOperation(models.Model): @classmethod def create(cls, backend, instance, action): - op = cls(backend=backend.get_name(), instance=instance, content_object=instance, action=action) + op = cls(backend=backend.get_name(), instance=instance, action=action) op.backend = backend return op diff --git a/orchestra/apps/orchestration/settings.py b/orchestra/apps/orchestration/settings.py index 1a2d0b45..86b17ac1 100644 --- a/orchestra/apps/orchestration/settings.py +++ b/orchestra/apps/orchestration/settings.py @@ -7,15 +7,19 @@ ORCHESTRATION_OS_CHOICES = getattr(settings, 'ORCHESTRATION_OS_CHOICES', ( ('LINUX', "Linux"), )) + ORCHESTRATION_DEFAULT_OS = getattr(settings, 'ORCHESTRATION_DEFAULT_OS', 'LINUX') + ORCHESTRATION_SSH_KEY_PATH = getattr(settings, 'ORCHESTRATION_SSH_KEY_PATH', path.join(path.expanduser('~'), '.ssh/id_rsa')) + ORCHESTRATION_ROUTER = getattr(settings, 'ORCHESTRATION_ROUTER', 'orchestra.apps.orchestration.models.Route' ) + ORCHESTRATION_TEMP_SCRIPT_PATH = getattr(settings, 'ORCHESTRATION_TEMP_SCRIPT_PATH', '/dev/shm' ) diff --git a/orchestra/apps/saas/services/dokuwiki.py b/orchestra/apps/saas/services/dokuwiki.py new file mode 100644 index 00000000..93690fd4 --- /dev/null +++ b/orchestra/apps/saas/services/dokuwiki.py @@ -0,0 +1,19 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from orchestra.forms import PluginDataForm + +from .options import SoftwareService + + +class DowkuwikiForm(PluginDataForm): + username = forms.CharField(label=_("Username"), max_length=64) + password = forms.CharField(label=_("Password"), max_length=64) + site_name = forms.CharField(label=_("Site name"), max_length=64) + email = forms.EmailField(label=_("Email")) + + +class DokuwikiService(SoftwareService): + verbose_name = "Dowkuwiki" + form = DowkuwikiForm + description_field = 'site_name' diff --git a/orchestra/apps/saas/services/drupal.py b/orchestra/apps/saas/services/drupal.py new file mode 100644 index 00000000..05318e21 --- /dev/null +++ b/orchestra/apps/saas/services/drupal.py @@ -0,0 +1,19 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from orchestra.forms import PluginDataForm + +from .options import SoftwareService + + +class DrupalForm(PluginDataForm): + username = forms.CharField(label=_("Username"), max_length=64) + password = forms.CharField(label=_("Password"), max_length=64) + site_name = forms.CharField(label=_("Site name"), max_length=64) + email = forms.EmailField(label=_("Email")) + + +class DrupalService(SoftwareService): + verbose_name = "Drupal" + form = DrupalForm + description_field = 'site_name' diff --git a/orchestra/apps/saas/services/moodle.py b/orchestra/apps/saas/services/moodle.py new file mode 100644 index 00000000..17e6da0c --- /dev/null +++ b/orchestra/apps/saas/services/moodle.py @@ -0,0 +1,19 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from orchestra.forms import PluginDataForm + +from .options import SoftwareService + + +class MoodleForm(PluginDataForm): + username = forms.CharField(label=_("Username"), max_length=64) + password = forms.CharField(label=_("Password"), max_length=64) + site_name = forms.CharField(label=_("Site name"), max_length=64) + email = forms.EmailField(label=_("Email")) + + +class MoodleService(SoftwareService): + verbose_name = "Moodle" + form = MoodleForm + description_field = 'site_name' diff --git a/orchestra/apps/saas/services/wordpress.py b/orchestra/apps/saas/services/wordpress.py new file mode 100644 index 00000000..677b86bd --- /dev/null +++ b/orchestra/apps/saas/services/wordpress.py @@ -0,0 +1,20 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from orchestra.forms import PluginDataForm + +from .options import SoftwareService + + +class WordpressForm(PluginDataForm): + username = forms.CharField(label=_("Username"), max_length=64) + password = forms.CharField(label=_("Password"), max_length=64) + site_name = forms.CharField(label=_("Site name"), max_length=64, + help_text=_("URL will be <site_name>.blogs.orchestra.lan")) + email = forms.EmailField(label=_("Email")) + + +class WordpressService(SoftwareService): + verbose_name = "Wordpress" + form = WordpressForm + description_field = 'site_name' diff --git a/orchestra/apps/saas/settings.py b/orchestra/apps/saas/settings.py index 2ba71ec9..c143b2f7 100644 --- a/orchestra/apps/saas/settings.py +++ b/orchestra/apps/saas/settings.py @@ -2,6 +2,10 @@ from django.conf import settings SAAS_ENABLED_SERVICES = getattr(settings, 'SAAS_ENABLED_SERVICES', ( + 'orchestra.apps.saas.services.wordpress.WordpressService', + 'orchestra.apps.saas.services.drupal.DrupalService', + 'orchestra.apps.saas.services.dokuwiki.DokuwikiService', + 'orchestra.apps.saas.services.moodle.MoodleService', 'orchestra.apps.saas.services.bscw.BSCWService', 'orchestra.apps.saas.services.gitlab.GitLabService', 'orchestra.apps.saas.services.phplist.PHPListService', diff --git a/orchestra/apps/saas/static/saas/icons/Dokuwiki.svg b/orchestra/apps/saas/static/saas/icons/Dokuwiki.svg new file mode 100644 index 00000000..cbee241e --- /dev/null +++ b/orchestra/apps/saas/static/saas/icons/Dokuwiki.svg @@ -0,0 +1,553 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/orchestra/apps/saas/static/saas/icons/Drupal.svg b/orchestra/apps/saas/static/saas/icons/Drupal.svg new file mode 100644 index 00000000..7da67bde --- /dev/null +++ b/orchestra/apps/saas/static/saas/icons/Drupal.svg @@ -0,0 +1 @@ +]>Druplicon \ No newline at end of file diff --git a/orchestra/apps/saas/static/saas/icons/Moodle.svg b/orchestra/apps/saas/static/saas/icons/Moodle.svg new file mode 100644 index 00000000..3ea6155d --- /dev/null +++ b/orchestra/apps/saas/static/saas/icons/Moodle.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/orchestra/apps/saas/static/saas/icons/WordPress.svg b/orchestra/apps/saas/static/saas/icons/WordPress.svg new file mode 100644 index 00000000..8628e3ad --- /dev/null +++ b/orchestra/apps/saas/static/saas/icons/WordPress.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/orchestra/apps/saas/static/saas/icons/gitlab.png b/orchestra/apps/saas/static/saas/icons/gitlab.png new file mode 100644 index 0000000000000000000000000000000000000000..09b1689ca455aaed6e30f7075a7972b8232fa75a GIT binary patch literal 32119 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μtWws*I&mrRkIh6Jxc;FFc44v>F zZ>Bg7k=lAIz*{nNapTo`PR6&YOlfJIE8)*^b;$`<_kncphh0602@U4?W}SABMHAWQDJthOV#C*-8h?2Wt1m&uF=#q1~kHVDH5CEZXrKvr@ zKL+qXJ<0sIyEj-To8sIPM#%+--ugB96s?k7(`#Cf6*p?ak*eJe&ka*&68d*eU2y^{ zM+cm3Qe5O9kUkrKsc*Cbo{ehUgjHZE)?_t1YG-^|dAle%At!P&07mg>V38bj*9I2E zU;VWo9@jSKCIIWbYc?yW?p4iH?I3kfk3Wzn-3Nhu0>|Ad5sjbNL>>v%n@*v>4I
+y?CxqDj`Rq1V9&GB8+rQm+$$A%0Ag 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 qOOF42(}R4\n' % token, - 'Hello World! %s' % token, - ) class RESTWebAppMixin(object): @@ -170,10 +164,18 @@ class AdminWebAppMixin(WebAppMixin): self.assertNotEqual(url, self.selenium.current_url) +class RESTWebAppTest(StaticWebAppMixin, RESTWebAppMixin, WebAppMixin, BaseLiveServerTestCase): + pass + + class RESTWebAppTest(PHPFcidWebAppMixin, RESTWebAppMixin, WebAppMixin, BaseLiveServerTestCase): pass +class RESTWebAppTest(PHPFPMWebAppMixin, RESTWebAppMixin, WebAppMixin, BaseLiveServerTestCase): + pass + + #class AdminWebAppTest(AdminWebAppMixin, BaseLiveServerTestCase): # pass diff --git a/orchestra/apps/websites/tests/functional_tests/tests.py b/orchestra/apps/websites/tests/functional_tests/tests.py index 7840a4a9..2095acd2 100644 --- a/orchestra/apps/websites/tests/functional_tests/tests.py +++ b/orchestra/apps/websites/tests/functional_tests/tests.py @@ -71,14 +71,12 @@ class RESTWebsiteMixin(RESTWebAppMixin): self.rest.websites.create(name=name, domains=[domain.url], contents=[{'webapp': webapp.url}]) - -#class RESTWebsiteTest(RESTWebsiteMixin, StaticWebAppMixin, WebsiteMixin, BaseLiveServerTestCase): -# pass +class RESTWebsiteTest(RESTWebsiteMixin, StaticWebAppMixin, WebsiteMixin, BaseLiveServerTestCase): + pass -PHPFPMWebAppMixin -#class RESTWebsiteTest(RESTWebsiteMixin, PHPFcidWebAppMixin, WebsiteMixin, BaseLiveServerTestCase): -# pass +class RESTWebsiteTest(RESTWebsiteMixin, PHPFcidWebAppMixin, WebsiteMixin, BaseLiveServerTestCase): + pass class RESTWebsiteTest(RESTWebsiteMixin, PHPFPMWebAppMixin, WebsiteMixin, BaseLiveServerTestCase):