diff --git a/docs/changelog.rst b/docs/changelog.rst index ead7ebe..12ea8c1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,7 @@ Changelog ========= +* :feature:`-` implement setup of websites * :support:`-` add webtasks interface * :support:`-` update to new fileservertasks interface (requires gvafile >= 0.4.0 on the fileserver) diff --git a/gnuviechadmin/gnuviechadmin/settings/base.py b/gnuviechadmin/gnuviechadmin/settings/base.py index 5effec9..f447d70 100644 --- a/gnuviechadmin/gnuviechadmin/settings/base.py +++ b/gnuviechadmin/gnuviechadmin/settings/base.py @@ -265,6 +265,7 @@ LOCAL_APPS = ( 'managemails', 'userdbs', 'hostingpackages', + 'websites', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py index 4dad925..7a79105 100644 --- a/gnuviechadmin/gnuviechadmin/urls.py +++ b/gnuviechadmin/gnuviechadmin/urls.py @@ -13,6 +13,7 @@ urlpatterns = patterns( url(r'^database/', include('userdbs.urls')), url(r'^domains/', include('domains.urls')), url(r'^hosting/', include('hostingpackages.urls')), + url(r'^website/', include('websites.urls')), url(r'^mail/', include('managemails.urls')), url(r'^osuser/', include('osusers.urls')), url(r'^admin/', include(admin.site.urls)), diff --git a/gnuviechadmin/templates/websites/base.html b/gnuviechadmin/templates/websites/base.html new file mode 100644 index 0000000..94d9808 --- /dev/null +++ b/gnuviechadmin/templates/websites/base.html @@ -0,0 +1 @@ +{% extends "base.html" %} diff --git a/gnuviechadmin/templates/websites/website_create.html b/gnuviechadmin/templates/websites/website_create.html new file mode 100644 index 0000000..3fb890f --- /dev/null +++ b/gnuviechadmin/templates/websites/website_create.html @@ -0,0 +1,30 @@ +{% extends "websites/base.html" %} +{% load i18n crispy_forms_tags %} + +{% block title %}{{ block.super }} - {% spaceless %} +{% if user == customer %} +{% blocktrans with domain=domain.domain %}Add Website for Subdomain of {{ domain }}{% endblocktrans %} +{% else %} +{% blocktrans with domain=domain.domain full_name=customer.get_full_name %}Add Website for Subdomain of Domain {{ domain }} of Customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock title %} + +{% block page_title %}{% spaceless %} +{% if user == customer %} +{% blocktrans with domain=domain.domain %}Add Website for Subdomain of {{ domain }}{% endblocktrans %} +{% else %} +{% blocktrans with domain=domain.domain full_name=customer.get_full_name %}Add Website for Subdomain of Domain {{ domain }} of Customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock page_title %} + +{% block content %} +{% crispy form %} +{% endblock %} + +{% block extra_js %} + +{% endblock extra_js %} diff --git a/gnuviechadmin/websites/admin.py b/gnuviechadmin/websites/admin.py index 8c38f3f..eeb47c8 100644 --- a/gnuviechadmin/websites/admin.py +++ b/gnuviechadmin/websites/admin.py @@ -1,3 +1,12 @@ +""" +Admin site for websites. + +""" +from __future__ import absolute_import + from django.contrib import admin -# Register your models here. +from .models import Website + + +admin.site.register(Website) diff --git a/gnuviechadmin/websites/forms.py b/gnuviechadmin/websites/forms.py new file mode 100644 index 0000000..a6fca20 --- /dev/null +++ b/gnuviechadmin/websites/forms.py @@ -0,0 +1,62 @@ +""" +This module defines form classes for website editing. + +""" +from __future__ import absolute_import, unicode_literals + +from django import forms +from django.core.urlresolvers import reverse +from django.utils.translation import ugettext as _ + +from crispy_forms.bootstrap import AppendedText +from crispy_forms.helper import FormHelper +from crispy_forms.layout import ( + Layout, + Submit, +) + +from .models import Website + + +class AddWebsiteForm(forms.ModelForm): + """ + This form is used to create new Website instances. + + """ + class Meta: + model = Website + fields = ['subdomain', 'wildcard'] + + def __init__(self, *args, **kwargs): + self.hosting_package = kwargs.pop('hostingpackage') + self.hosting_domain = kwargs.pop('domain') + super(AddWebsiteForm, self).__init__(*args, **kwargs) + if Website.objects.filter(wildcard=True).exists(): + self.fields['wildcard'].widget = forms.HiddenInput() + + self.helper = FormHelper() + self.helper.form_action = reverse( + 'add_website', kwargs={ + 'package': self.hosting_package.id, + 'domain': self.hosting_domain.domain, + } + ) + self.helper.layout = Layout( + AppendedText('subdomain', '.' + self.hosting_domain.domain), + 'wildcard', + Submit('submit', _('Add website')), + ) + + def clean_subdomain(self): + data = self.cleaned_data['subdomain'] + if Website.objects.filter( + domain=self.hosting_domain, subdomain=data + ).exists(): + raise forms.ValidationError( + _('There is already a website for this subdomain')) + return data + + def save(self, commit=True): + self.instance.domain = self.hosting_domain + self.instance.osuser = self.hosting_package.osuser + return super(AddWebsiteForm, self).save(commit) diff --git a/gnuviechadmin/websites/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/websites/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..ca2ee6e --- /dev/null +++ b/gnuviechadmin/websites/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,44 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: websites gnuviechadmin app\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-26 21:37+0100\n" +"PO-Revision-Date: 2015-01-26 21:39+0100\n" +"Last-Translator: Jan Dittberner \n" +"Language-Team: Jan Dittberner \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.6.10\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: models.py:22 +msgid "sub domain" +msgstr "Subdomain" + +#: models.py:24 +msgid "operating system user" +msgstr "Betriebssystemnutzer" + +#: models.py:26 +msgid "domain" +msgstr "Domain" + +#: models.py:27 +msgid "wildcard" +msgstr "Wildcard" + +#: models.py:31 +msgid "website" +msgstr "Webauftritt" + +#: models.py:32 +msgid "websites" +msgstr "Webauftritte" diff --git a/gnuviechadmin/websites/migrations/0001_initial.py b/gnuviechadmin/websites/migrations/0001_initial.py new file mode 100644 index 0000000..bfbb1a5 --- /dev/null +++ b/gnuviechadmin/websites/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osusers', '0004_auto_20150104_1751'), + ('domains', '0002_auto_20150124_1909'), + ] + + operations = [ + migrations.CreateModel( + name='Website', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('subdomain', models.CharField(max_length=64, verbose_name='sub domain')), + ('wildcard', models.BooleanField(default=False, verbose_name='wildcard')), + ('domain', models.ForeignKey(verbose_name='domain', to='domains.HostingDomain')), + ('osuser', models.ForeignKey(verbose_name='operating system user', to='osusers.User')), + ], + options={ + 'verbose_name': 'website', + 'verbose_name_plural': 'websites', + }, + bases=(models.Model,), + ), + migrations.AlterUniqueTogether( + name='website', + unique_together=set([('domain', 'subdomain')]), + ), + ] diff --git a/gnuviechadmin/websites/models.py b/gnuviechadmin/websites/models.py index 71a8362..2bc8928 100644 --- a/gnuviechadmin/websites/models.py +++ b/gnuviechadmin/websites/models.py @@ -1,3 +1,37 @@ -from django.db import models +""" +This module defines the database models for website handling. -# Create your models here. +""" +from __future__ import absolute_import, unicode_literals + +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from django.utils.translation import ugettext as _ + +from domains.models import HostingDomain +from osusers.models import User as OsUser + + +@python_2_unicode_compatible +class Website(models.Model): + """ + This is the model for a website. + + """ + subdomain = models.CharField( + _('sub domain'), max_length=64) + osuser = models.ForeignKey( + OsUser, verbose_name=_('operating system user')) + domain = models.ForeignKey( + HostingDomain, verbose_name=_('domain')) + wildcard = models.BooleanField(_('wildcard'), default=False) + + class Meta: + unique_together = [('domain', 'subdomain')] + verbose_name = _('website') + verbose_name_plural = _('websites') + + def __str__(self): + return "{subdomain}.{domain}".format( + subdomain=self.subdomain, domain=self.domain.domain + ) diff --git a/gnuviechadmin/websites/urls.py b/gnuviechadmin/websites/urls.py new file mode 100644 index 0000000..c98a252 --- /dev/null +++ b/gnuviechadmin/websites/urls.py @@ -0,0 +1,18 @@ +""" +This module defines the URL patterns for website related views. + +""" +from __future__ import absolute_import, unicode_literals + +from django.conf.urls import patterns, url + +from .views import ( + AddWebsite, +) + + +urlpatterns = patterns( + '', + url(r'^(?P\d+)/(?P[\w0-9.-]+)/create$', + AddWebsite.as_view(), name='add_website'), +) diff --git a/gnuviechadmin/websites/views.py b/gnuviechadmin/websites/views.py index 91ea44a..64a8fea 100644 --- a/gnuviechadmin/websites/views.py +++ b/gnuviechadmin/websites/views.py @@ -1,3 +1,60 @@ -from django.shortcuts import render +""" +This module defines views for website handling. -# Create your views here. +""" +from __future__ import absolute_import, unicode_literals + +from django.shortcuts import get_object_or_404, redirect +from django.utils.translation import ugettext as _ +from django.views.generic.edit import ( + CreateView, +) +from django.contrib import messages + +from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin +from gvawebcore.views import HostingPackageAndCustomerMixin + +from domains.models import HostingDomain +from .forms import AddWebsiteForm +from .models import Website + + +class AddWebsite( + HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView +): + """ + This view is used to setup new websites for a customer hosting package. + + """ + model = Website + context_object_name = 'website' + template_name_suffix = '_create' + form_class = AddWebsiteForm + + def get_form_kwargs(self): + kwargs = super(AddWebsite, self).get_form_kwargs() + kwargs.update({ + 'hostingpackage': self.get_hosting_package(), + 'domain': get_object_or_404( + HostingDomain, domain=self.kwargs['domain']), + }) + return kwargs + + def get_context_data(self, **kwargs): + context = super(AddWebsite, self).get_context_data(**kwargs) + context.update({ + 'customer': self.get_customer_object(), + 'domain': get_object_or_404( + HostingDomain, domain=self.kwargs['domain']) + }) + return context + + def form_valid(self, form): + website = form.save() + messages.success( + self.request, + _('Successfully added website {subdomain}.{domain}').format( + subdomain=website.subdomain, domain=website.domain.domain + ) + ) + return redirect(self.get_hosting_package())