Merge branch 'release/0.9.0' into production
* release/0.9.0: add release version in changelog, update conf.py add changelog entry mark bugs as major to include them in 0.7.0 changelog update translations, add new strings add code documentation for websites app implement websites.models.Website.delete implement website.models.Website.save implement domain name validation implement website deletion link from hostingpackage detail view to 'add_website' implement adding websites define User.is_sftp_user and fix minor template issues make manage.py executable add wildcard parameter to create_web_vhost_config task add django generated websites app add webtasks interface update to fileservertasks interface 0.4.0 version add new route 'web' for web server configuration
This commit is contained in:
commit
e718c472e8
38 changed files with 835 additions and 89 deletions
|
@ -1,6 +1,16 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
* :release:`0.9.0 <2015-01-27>`
|
||||
* :feature:`-` setup nginx virtual host and PHP configuration for websites
|
||||
(requires gvaweb >= 0.1.0 on web server)
|
||||
* :support:`-` implement domain name validation
|
||||
* :feature:`-` implement deletion of websites
|
||||
* :feature:`-` implement setup of websites
|
||||
* :support:`-` add webtasks interface
|
||||
* :support:`-` update to new fileservertasks interface (requires gvafile >=
|
||||
0.4.0 on the fileserver)
|
||||
|
||||
* :release:`0.8.0 <2015-01-26>`
|
||||
* :feature:`-` implement deletion of user database and database users
|
||||
* :feature:`-` implement password changes for database users
|
||||
|
@ -14,9 +24,9 @@ Changelog
|
|||
* :feature:`-` implement mail address deletion
|
||||
* :feature:`-` implement adding mail address to mail domains
|
||||
* :feature:`-` implement adding options to hosting packages
|
||||
* :bug:`-` fix disk space calculation in
|
||||
* :bug:`- major` fix disk space calculation in
|
||||
hostingpackages.models.CustomerHostingPackage
|
||||
* :bug:`-` fix unique constraints on
|
||||
* :bug:`- major` fix unique constraints on
|
||||
hostingpackages.models.CustomerDiskSpaceOption and
|
||||
hostingpackages.models.CustomerDatabaseOption
|
||||
* :feature:`-` implement password change functionality for mailboxes
|
||||
|
|
|
@ -27,6 +27,7 @@ Celery task stubs
|
|||
code/ldaptasks
|
||||
code/mysqltasks
|
||||
code/pgsqltasks
|
||||
code/webtasks
|
||||
|
||||
|
||||
Django app code
|
||||
|
@ -42,3 +43,4 @@ Django app code
|
|||
code/osusers
|
||||
code/taskresults
|
||||
code/userdbs
|
||||
code/websites
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
|
||||
:py:mod:`views <domains.views>`
|
||||
---------------------------------
|
||||
-------------------------------
|
||||
|
||||
.. automodule:: domains.views
|
||||
:members:
|
||||
|
|
46
docs/code/websites.rst
Normal file
46
docs/code/websites.rst
Normal file
|
@ -0,0 +1,46 @@
|
|||
:py:mod:`websites` app
|
||||
======================
|
||||
|
||||
.. automodule:: websites
|
||||
|
||||
|
||||
:py:mod:`admin <websites.admin>`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: websites.admin
|
||||
:members:
|
||||
|
||||
|
||||
:py:mod:`apps <websites.apps>`
|
||||
------------------------------
|
||||
|
||||
.. automodule:: websites.apps
|
||||
:members:
|
||||
|
||||
|
||||
:py:mod:`forms <websites.forms>`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: websites.forms
|
||||
:members:
|
||||
|
||||
|
||||
:py:mod:`models <websites.models>`
|
||||
----------------------------------
|
||||
|
||||
.. automodule:: websites.models
|
||||
:members:
|
||||
|
||||
|
||||
:py:mod:`urls <websites.urls>`
|
||||
------------------------------
|
||||
|
||||
.. automodule:: websites.urls
|
||||
:members:
|
||||
|
||||
|
||||
:py:mod:`views <websites.views>`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: websites.views
|
||||
:members:
|
12
docs/code/webtasks.rst
Normal file
12
docs/code/webtasks.rst
Normal file
|
@ -0,0 +1,12 @@
|
|||
:py:mod:`webtasks`
|
||||
==================
|
||||
|
||||
.. automodule:: webtasks
|
||||
|
||||
|
||||
:py:mod:`tasks <webtasks.tasks>`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: webtasks.tasks
|
||||
:members:
|
||||
:undoc-members:
|
|
@ -60,9 +60,9 @@ copyright = u'2014, 2015 Jan Dittberner'
|
|||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.8'
|
||||
version = '0.9'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.8.0'
|
||||
release = '0.9.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
@ -4,6 +4,8 @@ This module defines form classes for domain editing.
|
|||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from django import forms
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
|
@ -17,6 +19,18 @@ from crispy_forms.layout import (
|
|||
from .models import HostingDomain
|
||||
|
||||
|
||||
def relative_domain_validator(value):
|
||||
"""
|
||||
This validator ensures that the given value is a valid lowercase
|
||||
"""
|
||||
if len(value) > 254:
|
||||
raise forms.ValidationError(
|
||||
_('host name too long'), code='too-long')
|
||||
allowed = re.compile(r"(?!-)[a-z\d-]{1,63}(?<!-)$")
|
||||
if not all(allowed.match(x) for x in value.split('.')):
|
||||
raise forms.ValidationError(_('invalid domain name'))
|
||||
|
||||
|
||||
class CreateHostingDomainForm(forms.ModelForm):
|
||||
"""
|
||||
This form is used to create new HostingDomain instances.
|
||||
|
@ -29,6 +43,7 @@ class CreateHostingDomainForm(forms.ModelForm):
|
|||
def __init__(self, instance, *args, **kwargs):
|
||||
self.hosting_package = kwargs.pop('hostingpackage')
|
||||
super(CreateHostingDomainForm, self).__init__(*args, **kwargs)
|
||||
self.fields['domain'].validators.append(relative_domain_validator)
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_action = reverse(
|
||||
'create_hosting_domain', kwargs={
|
||||
|
|
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gnuviechadmin domains\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-25 00:46+0100\n"
|
||||
"PO-Revision-Date: 2015-01-25 00:56+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-27 19:06+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language: de\n"
|
||||
|
@ -23,7 +23,15 @@ msgstr ""
|
|||
msgid "Domains"
|
||||
msgstr "Domains"
|
||||
|
||||
#: domains/forms.py:39
|
||||
#: domains/forms.py:28
|
||||
msgid "host name too long"
|
||||
msgstr "zu langer Hostname"
|
||||
|
||||
#: domains/forms.py:31
|
||||
msgid "invalid domain name"
|
||||
msgstr "ungültiger Domainname"
|
||||
|
||||
#: domains/forms.py:54
|
||||
msgid "Add Hosting Domain"
|
||||
msgstr "Hostingdomain hinzufügen"
|
||||
|
||||
|
|
|
@ -92,3 +92,29 @@ def delete_file_mailbox(username, mailboxname):
|
|||
:rtype: str
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@shared_task
|
||||
def create_file_website_hierarchy(username, sitename):
|
||||
"""
|
||||
This task creates the directory hierarchy for a website.
|
||||
|
||||
:param str username: the user name
|
||||
:param str sitename: name of the website
|
||||
:return: the directory name
|
||||
:rtype: str
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@shared_task
|
||||
def delete_file_website_hierarchy(username, sitename):
|
||||
"""
|
||||
This task deletes the website hierarchy recursively.
|
||||
|
||||
:param str username: the user name
|
||||
:param str sitename: name of the website
|
||||
:return: the directory name
|
||||
:rtype: str
|
||||
|
||||
"""
|
||||
|
|
|
@ -258,11 +258,14 @@ LOCAL_APPS = (
|
|||
'taskresults',
|
||||
'mysqltasks',
|
||||
'pgsqltasks',
|
||||
'fileservertasks',
|
||||
'webtasks',
|
||||
'domains',
|
||||
'osusers',
|
||||
'managemails',
|
||||
'userdbs',
|
||||
'hostingpackages',
|
||||
'websites',
|
||||
)
|
||||
|
||||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||
class GvaRouter(object):
|
||||
|
||||
def route_for_task(self, task, args=None, kwargs=None):
|
||||
for route in ['ldap', 'file', 'mysql', 'pgsql']:
|
||||
for route in ['ldap', 'file', 'mysql', 'pgsql', 'web']:
|
||||
if route in task:
|
||||
return {
|
||||
'exchange': route,
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gvacommon\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-24 17:40+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-24 18:25+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gvawebcore\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-25 11:49+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-25 11:49+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
@ -19,14 +19,14 @@ msgstr ""
|
|||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
|
||||
#: forms.py:12
|
||||
#: gvawebcore/forms.py:12
|
||||
msgid "Passwords don't match"
|
||||
msgstr "Passwörter stimmen nicht überein"
|
||||
|
||||
#: forms.py:25
|
||||
#: gvawebcore/forms.py:25
|
||||
msgid "Password"
|
||||
msgstr "Passwort: "
|
||||
|
||||
#: forms.py:28
|
||||
#: gvawebcore/forms.py:28
|
||||
msgid "Password (again)"
|
||||
msgstr "Passwortwiederholung"
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gnuviechadmin hostingpackages\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-25 15:46+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-25 15:49+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
@ -215,19 +215,19 @@ msgstr "Die Postfachoptionsvorlage auf der diese Postfachoption aufgebaut ist"
|
|||
msgid "Started setup of new hosting package {name}."
|
||||
msgstr "Einrichtung des Hostingpakets {name} wurde gestartet."
|
||||
|
||||
#: hostingpackages/views.py:146
|
||||
#: hostingpackages/views.py:152
|
||||
msgid "Disk space"
|
||||
msgstr "Speicherplatz"
|
||||
|
||||
#: hostingpackages/views.py:149
|
||||
#: hostingpackages/views.py:155
|
||||
msgid "Mailboxes"
|
||||
msgstr "Postfächer"
|
||||
|
||||
#: hostingpackages/views.py:152
|
||||
#: hostingpackages/views.py:158
|
||||
msgid "Databases"
|
||||
msgstr "Datenbanken"
|
||||
|
||||
#: hostingpackages/views.py:222
|
||||
#: hostingpackages/views.py:228
|
||||
#, python-brace-format
|
||||
msgid "Successfully added option {option} to hosting package {package}."
|
||||
msgstr "Option {option} erfolgreich zum Hostingpaket {package} hinzugefügt."
|
||||
|
|
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gnuviechadmin\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-26 13:42+0100\n"
|
||||
"PO-Revision-Date: 2015-01-26 13:51+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-27 19:06+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language: de\n"
|
||||
|
@ -524,14 +524,14 @@ msgid "Mailboxes"
|
|||
msgstr "Postfächer"
|
||||
|
||||
#: templates/dashboard/user_dashboard.html:18
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:163
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:176
|
||||
msgid "Databases"
|
||||
msgstr "Datenbanken"
|
||||
|
||||
#: templates/dashboard/user_dashboard.html:19
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:86
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:136
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:171
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:149
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:184
|
||||
msgid "Actions"
|
||||
msgstr "Aktionen"
|
||||
|
||||
|
@ -715,7 +715,7 @@ msgid "Domain name"
|
|||
msgstr "Domainname"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:84
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:134
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:147
|
||||
msgid "Mail addresses"
|
||||
msgstr "E-Mailadressen"
|
||||
|
||||
|
@ -735,88 +735,97 @@ msgstr "E-Mailadressziele bearbeiten"
|
|||
msgid "Delete mail address"
|
||||
msgstr "E-Mailadresse löschen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:104
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:103
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:115
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:109
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:110
|
||||
msgid "Delete website"
|
||||
msgstr "Webauftritt löschen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:119
|
||||
msgid "Add mail address"
|
||||
msgstr "E-Mailadresse hinzufügen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:117
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:122
|
||||
msgid "Add website"
|
||||
msgstr "Webauftritt anlegen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:130
|
||||
msgid "There are no domains assigned to this hosting package yet."
|
||||
msgstr "Diesem Paket sind noch keine Domains zugeordnet."
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:120
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:133
|
||||
msgid "Add domain"
|
||||
msgstr "Domain hinzufügen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:128
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:141
|
||||
msgid "E-Mail-Accounts"
|
||||
msgstr "E-Mailkonten"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:133
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:146
|
||||
msgid "Mailbox"
|
||||
msgstr "Postfach"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:135
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:144
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:148
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:157
|
||||
msgid "Active"
|
||||
msgstr "Aktiv"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:136
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:149
|
||||
msgid "Mailbox actions"
|
||||
msgstr "Postfachaktionen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:144
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:157
|
||||
msgid "inactive"
|
||||
msgstr "inaktiv"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:146
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:159
|
||||
msgid "Set mailbox password"
|
||||
msgstr "Postfachpasswort setzen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:152
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:165
|
||||
msgid "There are no mailboxes assigned to this hosting package yet."
|
||||
msgstr "Diesem Hostingpaket sind noch keine Postfächer zugeordnet."
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:155
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:168
|
||||
msgid "Add mailbox"
|
||||
msgstr "Postfach hinzufügen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:168
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:181
|
||||
msgid "Database name"
|
||||
msgstr "Datenbankname"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:169
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:182
|
||||
msgid "Database user"
|
||||
msgstr "Datenbanknutzer"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:170
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:183
|
||||
msgid "Database type"
|
||||
msgstr "Datenbanktyp"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:170
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:183
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:171
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:184
|
||||
msgid "Database actions"
|
||||
msgstr "Datenbankaktionen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:181
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:194
|
||||
msgid "Set database user password"
|
||||
msgstr "Datenbanknutzerpasswort setzen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:182
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:195
|
||||
msgid "Delete database"
|
||||
msgstr "Datenbank löschen"
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:189
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:202
|
||||
msgid "There are no databases assigned to this hosting package yet."
|
||||
msgstr "Diesem Hostingpaket sind noch keine Datenbanken zugeordnet."
|
||||
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:192
|
||||
#: templates/hostingpackages/customerhostingpackage_detail.html:205
|
||||
msgid "Add database"
|
||||
msgstr "Datenbank hinzufügen"
|
||||
|
||||
|
@ -848,11 +857,13 @@ msgstr "Wollen Sie die E-Mailadresse %(mailaddress)s wirklich löschen?"
|
|||
|
||||
#: templates/managemails/mailaddress_confirm_delete.html:28
|
||||
#: templates/userdbs/userdatabase_confirm_delete.html:29
|
||||
#: templates/websites/website_confirm_delete.html:29
|
||||
msgid "Yes, do it!"
|
||||
msgstr "Ja, so soll es sein!"
|
||||
|
||||
#: templates/managemails/mailaddress_confirm_delete.html:29
|
||||
#: templates/userdbs/userdatabase_confirm_delete.html:30
|
||||
#: templates/websites/website_confirm_delete.html:30
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
|
@ -1118,6 +1129,71 @@ msgstr ""
|
|||
"Bitte geben Sie ein Passwort für den neuen Datenbanknutzer für Ihre "
|
||||
"Datenbank ein."
|
||||
|
||||
#: templates/websites/website_confirm_delete.html:6
|
||||
#, python-format
|
||||
msgid "Delete Website %(website)s"
|
||||
msgstr "Webauftritt %(website)s löschen"
|
||||
|
||||
#: templates/websites/website_confirm_delete.html:8
|
||||
#, python-format
|
||||
msgid "Delete Website %(website)s of Customer %(full_name)s"
|
||||
msgstr "Webauftritt %(website)s des Kunden %(full_name)s löschen"
|
||||
|
||||
#: templates/websites/website_confirm_delete.html:14
|
||||
#, python-format
|
||||
msgid "Delete Website <small>%(website)s</small>"
|
||||
msgstr "Webauftritt löschen <small>%(website)s</small>"
|
||||
|
||||
#: templates/websites/website_confirm_delete.html:16
|
||||
#, python-format
|
||||
msgid "Delete Website <small>%(website)s of Customer %(full_name)s</small>"
|
||||
msgstr ""
|
||||
"Webauftritt löschen <small>%(website)s des Kunden %(full_name)s</small>"
|
||||
|
||||
#: templates/websites/website_confirm_delete.html:23
|
||||
#, python-format
|
||||
msgid "Do you really want to delete the website %(website)s?"
|
||||
msgstr "Wollen Sie den Webauftritt %(website)s wirklich löschen?"
|
||||
|
||||
#: templates/websites/website_confirm_delete.html:26
|
||||
msgid ""
|
||||
"Please be aware that the website directory is removed from the webserver and "
|
||||
"the webserver configuration is changed so that the website will not be "
|
||||
"reachable anymore. <strong>All data in the website directory will be lost!</"
|
||||
"strong>"
|
||||
msgstr ""
|
||||
"Bitte beachten Sie, dass das Verzeichnis des Webauftritts vom Webserver "
|
||||
"gelöscht und die Konfiguration so angepasst wird, dass der Webauftritt nicht "
|
||||
"mehr erreichbar sein wird. <strong>Alle Daten im Verzeichnis des "
|
||||
"Webauftritts werden verloren gehen!</strong>"
|
||||
|
||||
#: templates/websites/website_create.html:6
|
||||
#, python-format
|
||||
msgid "Add Website for Subdomain of %(domain)s"
|
||||
msgstr "Webauftritt für Subdomain von %(domain)s anlegen"
|
||||
|
||||
#: templates/websites/website_create.html:8
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Add Website for Subdomain of Domain %(domain)s of Customer %(full_name)s"
|
||||
msgstr ""
|
||||
"Webauftritt für Subdomain der Domain %(domain)s des Kunden %(full_name)s "
|
||||
"anlegen"
|
||||
|
||||
#: templates/websites/website_create.html:14
|
||||
#, python-format
|
||||
msgid "Add Website <small>for Subdomain of %(domain)s</small>"
|
||||
msgstr "Website anlegen <small>für Subdomain von %(domain)s</small>"
|
||||
|
||||
#: templates/websites/website_create.html:16
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Add Website <small>for Subdomain of Domain %(domain)s of Customer "
|
||||
"%(full_name)s</small>"
|
||||
msgstr ""
|
||||
"Webauftritt anlegen <small>für Subdomain der Domain %(domain)s des Kunden "
|
||||
"%(full_name)s</small>"
|
||||
|
||||
#, fuzzy
|
||||
#~| msgid "Password Reset"
|
||||
#~ msgid "Password (again)"
|
||||
|
|
0
gnuviechadmin/manage.py
Normal file → Executable file
0
gnuviechadmin/manage.py
Normal file → Executable file
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: managemails\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-25 22:13+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-25 22:17+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
@ -124,27 +124,27 @@ msgstr "E-Mailadresse"
|
|||
msgid "mailbox"
|
||||
msgstr "Postfach"
|
||||
|
||||
#: managemails/views.py:71
|
||||
#: managemails/views.py:51
|
||||
msgid "You are not allowed to add more mailboxes to this hosting package"
|
||||
msgstr "Sie können keine weiteren Postfächer zu diesem Hostingpaket hinzufügen"
|
||||
|
||||
#: managemails/views.py:90
|
||||
#: managemails/views.py:70
|
||||
#, python-brace-format
|
||||
msgid "Mailbox {mailbox} created successfully."
|
||||
msgstr "Postfach {mailbox} erfolgreich angelegt."
|
||||
|
||||
#: managemails/views.py:125
|
||||
#: managemails/views.py:105
|
||||
#, python-brace-format
|
||||
msgid "Successfully set new password for mailbox {mailbox}."
|
||||
msgstr ""
|
||||
"Für das Postfach {mailbox} wurde erfolgreich ein neues Passwort gesetzt."
|
||||
|
||||
#: managemails/views.py:164
|
||||
#: managemails/views.py:144
|
||||
#, python-brace-format
|
||||
msgid "Successfully added mail address {mailaddress}"
|
||||
msgstr "E-Mailadresse {mailaddress} erfolgreich hinzugefügt"
|
||||
|
||||
#: managemails/views.py:242
|
||||
#: managemails/views.py:222
|
||||
#, python-brace-format
|
||||
msgid "Successfully updated mail address {mailaddress} targets."
|
||||
msgstr "Ziele der E-Mailadresse {mailaddress} erfolgreich aktualisiert."
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: osusers\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-24 17:40+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-24 18:25+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
@ -19,11 +19,11 @@ msgstr ""
|
|||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
|
||||
#: osusers/admin.py:45 osusers/forms.py:28
|
||||
#: osusers/admin.py:45
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: osusers/admin.py:49 osusers/forms.py:32
|
||||
#: osusers/admin.py:49
|
||||
msgid "Password (again)"
|
||||
msgstr "Passwortwiederholung"
|
||||
|
||||
|
@ -39,11 +39,7 @@ msgstr "Ausgewählte Gruppen löschen"
|
|||
msgid "Operating System Users and Groups"
|
||||
msgstr "Betriebssystemnutzer- und Gruppen"
|
||||
|
||||
#: osusers/forms.py:16
|
||||
msgid "Passwords don't match"
|
||||
msgstr "Passwörter stimmen nicht überein"
|
||||
|
||||
#: osusers/forms.py:45
|
||||
#: osusers/forms.py:33
|
||||
msgid "Set password"
|
||||
msgstr "Passwort setzen"
|
||||
|
||||
|
@ -95,7 +91,7 @@ msgstr "Home-Verzeichnis"
|
|||
msgid "Login shell"
|
||||
msgstr "Loginshell"
|
||||
|
||||
#: osusers/models.py:230 osusers/models.py:366
|
||||
#: osusers/models.py:230 osusers/models.py:370
|
||||
msgid "User"
|
||||
msgstr "Nutzer"
|
||||
|
||||
|
@ -103,48 +99,48 @@ msgstr "Nutzer"
|
|||
msgid "Users"
|
||||
msgstr "Nutzer"
|
||||
|
||||
#: osusers/models.py:367
|
||||
#: osusers/models.py:371
|
||||
msgid "Encrypted password"
|
||||
msgstr "Verschlüsseltes Passwort"
|
||||
|
||||
#: osusers/models.py:369
|
||||
#: osusers/models.py:373
|
||||
msgid "Date of last change"
|
||||
msgstr "Datum der letzten Änderung"
|
||||
|
||||
#: osusers/models.py:370
|
||||
#: osusers/models.py:374
|
||||
msgid "This is expressed in days since Jan 1, 1970"
|
||||
msgstr "Ausgedrückt als Tage seit dem 1. Januar 1970"
|
||||
|
||||
#: osusers/models.py:373
|
||||
#: osusers/models.py:377
|
||||
msgid "Minimum age"
|
||||
msgstr "Minimales Alter"
|
||||
|
||||
#: osusers/models.py:374
|
||||
#: osusers/models.py:378
|
||||
msgid "Minimum number of days before the password can be changed"
|
||||
msgstr "Minmale Anzahl von Tagen bevor das Passwort geändert werden kann"
|
||||
|
||||
#: osusers/models.py:378
|
||||
#: osusers/models.py:382
|
||||
msgid "Maximum age"
|
||||
msgstr "Maximales Alter"
|
||||
|
||||
#: osusers/models.py:379
|
||||
#: osusers/models.py:383
|
||||
msgid "Maximum number of days after which the password has to be changed"
|
||||
msgstr ""
|
||||
"Maximale Anzahl von Tagen, nach denen das Passwort geändert werden muss"
|
||||
|
||||
#: osusers/models.py:383
|
||||
#: osusers/models.py:387
|
||||
msgid "Grace period"
|
||||
msgstr "Duldungsperiode"
|
||||
|
||||
#: osusers/models.py:384
|
||||
#: osusers/models.py:388
|
||||
msgid "The number of days before the password is going to expire"
|
||||
msgstr "Anzahl von Tagen nach denen das Passwort verfällt"
|
||||
|
||||
#: osusers/models.py:388
|
||||
#: osusers/models.py:392
|
||||
msgid "Inactivity period"
|
||||
msgstr "Inaktivitätsperiode"
|
||||
|
||||
#: osusers/models.py:389
|
||||
#: osusers/models.py:393
|
||||
msgid ""
|
||||
"The number of days after the password has expired during which the password "
|
||||
"should still be accepted"
|
||||
|
@ -152,29 +148,29 @@ msgstr ""
|
|||
"Die Anzahl von Tagen für die ein verfallenes Passwort noch akzeptiert werden "
|
||||
"soll"
|
||||
|
||||
#: osusers/models.py:393
|
||||
#: osusers/models.py:397
|
||||
msgid "Account expiration date"
|
||||
msgstr "Kontoverfallsdatum"
|
||||
|
||||
#: osusers/models.py:394
|
||||
#: osusers/models.py:398
|
||||
msgid ""
|
||||
"The date of expiration of the account, expressed as number of days since Jan "
|
||||
"1, 1970"
|
||||
msgstr "Kontoverfallsdatum in Tagen seit dem 1. Januar 1970"
|
||||
|
||||
#: osusers/models.py:401
|
||||
#: osusers/models.py:405
|
||||
msgid "Shadow password"
|
||||
msgstr "Shadow-Passwort"
|
||||
|
||||
#: osusers/models.py:402
|
||||
#: osusers/models.py:406
|
||||
msgid "Shadow passwords"
|
||||
msgstr "Shadow-Passwörter"
|
||||
|
||||
#: osusers/models.py:428
|
||||
#: osusers/models.py:432
|
||||
msgid "Additional group"
|
||||
msgstr "Weitere Gruppe"
|
||||
|
||||
#: osusers/models.py:429
|
||||
#: osusers/models.py:433
|
||||
msgid "Additional groups"
|
||||
msgstr "Weitere Gruppen"
|
||||
|
||||
|
@ -182,3 +178,6 @@ msgstr "Weitere Gruppen"
|
|||
#, python-brace-format
|
||||
msgid "New password for {username} has been set successfully."
|
||||
msgstr "Für {username} wurde erfolgreich ein neues Passwort gesetzt."
|
||||
|
||||
#~ msgid "Passwords don't match"
|
||||
#~ msgstr "Passwörter stimmen nicht überein"
|
||||
|
|
|
@ -266,6 +266,10 @@ class User(TimeStampedModel, models.Model):
|
|||
_LOGGER.info("set LDAP password for %s", dn)
|
||||
return True
|
||||
|
||||
def is_sftp_user(self):
|
||||
return self.additionalgroup_set.filter(
|
||||
group__groupname=settings.OSUSER_SFTP_GROUP
|
||||
).exists()
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gnuviechadmin taskresults\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-17 15:59+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-17 16:00+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
{% endwith %}
|
||||
<dt>{% trans "Mailboxes" %}</dt>
|
||||
<dd>{% blocktrans with num=hostingpackage.used_mailbox_count total=hostingpackage.mailbox_count %}{{ num }} of {{ total }} in use{% endblocktrans %} <span class="glyphicon
|
||||
glyphicon-info-sign" title="{% blocktrans with mailboxes=hostingpackage.mailboxcount %}The package provides {{ mailboxcount }} mailboxes the difference comes from mailbox options.{% endblocktrans %}"></span></dd>
|
||||
glyphicon-info-sign" title="{% blocktrans with mailboxcount=hostingpackage.mailboxcount %}The package provides {{ mailboxcount }} mailboxes the difference comes from mailbox options.{% endblocktrans %}"></span></dd>
|
||||
<dt>{% if osuser.is_sftp_user %}{% trans "SFTP username" %}{% else %}{% trans "SSH/SFTP username" %}{% endif %}</dt>
|
||||
<dd>{{ osuser.username }}</dd>
|
||||
<dt>{% trans "Upload server" %}</dt>
|
||||
|
@ -67,7 +67,7 @@
|
|||
<div class="panel-heading">{% trans "Hosting Package Actions" %}</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item"><a href="#" title="{% trans "Edit Hosting Package Description" %}">{% trans "Edit description" %}</a></li>
|
||||
<li class="list-group-item"><a href="{% url "set_osuser_password" slug=osuser.username %}">{% if osuser.is_sftp %}{% trans "Set SFTP password" %}{% else %}{% trans "Set SSH/SFTP password" %}{% endif %}</a></li>
|
||||
<li class="list-group-item"><a href="{% url "set_osuser_password" slug=osuser.username %}">{% if osuser.is_sftp_user %}{% trans "Set SFTP password" %}{% else %}{% trans "Set SSH/SFTP password" %}{% endif %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -90,23 +90,36 @@
|
|||
{% for domain in domains %}
|
||||
<tr>
|
||||
<td>{{ domain.domain }}</td>
|
||||
{% if domain.domain.maildomain %}
|
||||
{% if domain.domain.maildomain.mailaddress_set.exists %}
|
||||
<td>
|
||||
{% with maildomain=domain.domain.maildomain %}
|
||||
{% for mailaddress in maildomain.mailaddresses %}{% spaceless %}
|
||||
<a href="{% url 'edit_mailaddress' package=hostingpackage.id domain=maildomain.domain pk=mailaddress.id %}" title="{% trans "Edit mail address targets" %}">{{ mailaddress }}</a>
|
||||
<a href="{% url 'delete_mailaddress' package=hostingpackage.id domain=maildomain.domain pk=mailaddress.id %}" title="{% trans "Delete mail address" %}"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
{% endspaceless %}{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
<a href="{% url 'delete_mailaddress' package=hostingpackage.id domain=maildomain.domain pk=mailaddress.id %}" title="{% trans "Delete mail address" %}"><i class="glyphicon glyphicon-trash"></i><span class="sr-only"> {% trans "Delete mail address" %}</span></a>
|
||||
{% endspaceless %}{% if not forloop.last %}, {% endif %}{% endfor %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="text-info">{% trans "None" %}</td>
|
||||
{% endif %}
|
||||
{% if domain.domain.website_set.exists %}
|
||||
<td>
|
||||
{% with domain=domain.domain %}
|
||||
{% for website in domain.website_set.all %}{% spaceless %}
|
||||
{{ website }}
|
||||
<a href="{% url 'delete_website' package=hostingpackage.id domain=domain.domain pk=website.id %}" titel="{% trans "Delete website" %}"><i class="glyphicon glyphicon-trash"></i><span class="sr-only"> {% trans "Delete website" %}</span></a>
|
||||
{% endspaceless %}{% if not forloop.last %}, {% endif %}{% endfor %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="text-info">{% trans "None" %}</td>
|
||||
{% endif %}
|
||||
<td></td>
|
||||
<td>
|
||||
{% with maildomain=domain.domain.maildomain %}
|
||||
<a href="{% url 'add_mailaddress' package=hostingpackage.id domain=maildomain.domain %}" title="{% trans "Add mail address" %}"><i class="fa fa-envelope"></i></a>
|
||||
<a href="{% url 'add_mailaddress' package=hostingpackage.id domain=maildomain.domain %}" title="{% trans "Add mail address" %}"><i class="fa fa-envelope"></i><span class="sr-only"> {% trans "Add mail address" %}</span></a>
|
||||
{% endwith %}
|
||||
{% with hostingdomain=domain.domain %}
|
||||
<a href="{% url 'add_website' package=hostingpackage.id domain=hostingdomain.domain %}" title="{% trans "Add website" %}"><i class="glyphicon glyphicon-globe"></i><span class="sr-only"> {% trans "Add website" %}</span></a>
|
||||
{% endwith %}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
1
gnuviechadmin/templates/websites/base.html
Normal file
1
gnuviechadmin/templates/websites/base.html
Normal file
|
@ -0,0 +1 @@
|
|||
{% extends "base.html" %}
|
34
gnuviechadmin/templates/websites/website_confirm_delete.html
Normal file
34
gnuviechadmin/templates/websites/website_confirm_delete.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
{% extends "websites/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ block.super }} - {% spaceless %}
|
||||
{% if user == customer %}
|
||||
{% blocktrans %}Delete Website {{ website }}{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with full_name=customer.get_full_name %}Delete Website {{ website }} of Customer {{ full_name }}{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% endspaceless %}{% endblock title %}
|
||||
|
||||
{% block page_title %}{% spaceless %}
|
||||
{% if user == customer %}
|
||||
{% blocktrans %}Delete Website <small>{{ website }}</small>{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with full_name=customer.get_full_name %}Delete Website <small>{{ website }} of Customer {{ full_name }}</small>{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% endspaceless %}{% endblock page_title %}
|
||||
|
||||
{% block content %}
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
{% blocktrans %}Do you really want to delete the website {{ website }}?{% endblocktrans %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p>{% blocktrans %}Please be aware that the website directory is removed from the webserver and the webserver configuration is changed so that the website will not be reachable anymore. <strong>All data in the website directory will be lost!</strong>{% endblocktrans %}</p>
|
||||
<form action="{% url 'delete_website' package=hostingpackage.id domain=website.domain.domain pk=website.id %}" method="post" class="form">
|
||||
{% csrf_token %}
|
||||
<input class="btn btn-warning" type="submit" value="{% trans "Yes, do it!" %}" />
|
||||
<a class="btn btn-default" href="{{ hostingpackage.get_absolute_url }}">{% trans "Cancel" %}</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
30
gnuviechadmin/templates/websites/website_create.html
Normal file
30
gnuviechadmin/templates/websites/website_create.html
Normal file
|
@ -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 <small>for Subdomain of {{ domain }}</small>{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with domain=domain.domain full_name=customer.get_full_name %}Add Website <small>for Subdomain of Domain {{ domain }} of Customer {{ full_name }}</small>{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% endspaceless %}{% endblock page_title %}
|
||||
|
||||
{% block content %}
|
||||
{% crispy form %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('input[type=text]').first().focus();
|
||||
});
|
||||
</script>
|
||||
{% endblock extra_js %}
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gnuviechadmin userdbs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-26 13:42+0100\n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-26 13:44+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\n"
|
||||
|
|
5
gnuviechadmin/websites/__init__.py
Normal file
5
gnuviechadmin/websites/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
"""
|
||||
This app takes care of websites.
|
||||
|
||||
"""
|
||||
default_app_config = 'websites.apps.WebsitesAppConfig'
|
12
gnuviechadmin/websites/admin.py
Normal file
12
gnuviechadmin/websites/admin.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
"""
|
||||
Admin site for websites.
|
||||
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Website
|
||||
|
||||
|
||||
admin.site.register(Website)
|
17
gnuviechadmin/websites/apps.py
Normal file
17
gnuviechadmin/websites/apps.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
"""
|
||||
This module contains the :py:class:`django.apps.AppConfig` instance for the
|
||||
:py:mod:`websites` app.
|
||||
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class WebsitesAppConfig(AppConfig):
|
||||
"""
|
||||
AppConfig for the :py:mod:`websites` app.
|
||||
|
||||
"""
|
||||
name = 'websites'
|
||||
verbose_name = _('Websites')
|
68
gnuviechadmin/websites/forms.py
Normal file
68
gnuviechadmin/websites/forms.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
"""
|
||||
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 domains.forms import relative_domain_validator
|
||||
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)
|
||||
self.fields['subdomain'].validators.append(relative_domain_validator)
|
||||
if Website.objects.filter(
|
||||
wildcard=True, domain=self.hosting_domain
|
||||
).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'))
|
||||
relative_domain_validator(
|
||||
"{0}.{1}".format(data, self.hosting_domain.domain))
|
||||
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)
|
61
gnuviechadmin/websites/locale/de/LC_MESSAGES/django.po
Normal file
61
gnuviechadmin/websites/locale/de/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,61 @@
|
|||
# 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 <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: websites gnuviechadmin app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-27 18:55+0100\n"
|
||||
"PO-Revision-Date: 2015-01-27 19:00+0100\n"
|
||||
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
|
||||
"Language-Team: Jan Dittberner <jan@dittberner.info>\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"
|
||||
|
||||
#: websites/apps.py:17
|
||||
msgid "Websites"
|
||||
msgstr "Webauftritte"
|
||||
|
||||
#: websites/forms.py:51
|
||||
msgid "Add website"
|
||||
msgstr "Webauftritt anlegen"
|
||||
|
||||
#: websites/forms.py:60
|
||||
msgid "There is already a website for this subdomain"
|
||||
msgstr "Es gibt bereits einen Webauftritt mit dieser Subdomain"
|
||||
|
||||
#: websites/models.py:35
|
||||
msgid "sub domain"
|
||||
msgstr "Subdomain"
|
||||
|
||||
#: websites/models.py:37
|
||||
msgid "operating system user"
|
||||
msgstr "Betriebssystemnutzer"
|
||||
|
||||
#: websites/models.py:39
|
||||
msgid "domain"
|
||||
msgstr "Domain"
|
||||
|
||||
#: websites/models.py:40
|
||||
msgid "wildcard"
|
||||
msgstr "Wildcard"
|
||||
|
||||
#: websites/models.py:44
|
||||
msgid "website"
|
||||
msgstr "Webauftritt"
|
||||
|
||||
#: websites/models.py:45
|
||||
msgid "websites"
|
||||
msgstr "Webauftritte"
|
||||
|
||||
#: websites/views.py:57
|
||||
#, python-brace-format
|
||||
msgid "Successfully added website {subdomain}.{domain}"
|
||||
msgstr "Webauftritt {subdomain}.{domain} erfolgreich angelegt"
|
34
gnuviechadmin/websites/migrations/0001_initial.py
Normal file
34
gnuviechadmin/websites/migrations/0001_initial.py
Normal file
|
@ -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')]),
|
||||
),
|
||||
]
|
0
gnuviechadmin/websites/migrations/__init__.py
Normal file
0
gnuviechadmin/websites/migrations/__init__.py
Normal file
79
gnuviechadmin/websites/models.py
Normal file
79
gnuviechadmin/websites/models.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
"""
|
||||
This module defines the database models for website handling.
|
||||
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.db import models, transaction
|
||||
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
|
||||
|
||||
from fileservertasks.tasks import (
|
||||
create_file_website_hierarchy,
|
||||
delete_file_website_hierarchy,
|
||||
)
|
||||
from webtasks.tasks import (
|
||||
create_web_php_fpm_pool_config,
|
||||
create_web_vhost_config,
|
||||
delete_web_php_fpm_pool_config,
|
||||
delete_web_vhost_config,
|
||||
disable_web_vhost,
|
||||
enable_web_vhost,
|
||||
)
|
||||
|
||||
|
||||
@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 self.get_fqdn()
|
||||
|
||||
def get_fqdn(self):
|
||||
return "{subdomain}.{domain}".format(
|
||||
subdomain=self.subdomain, domain=self.domain.domain
|
||||
)
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.pk:
|
||||
fqdn = self.get_fqdn()
|
||||
if not Website.objects.filter(osuser=self.osuser).exists():
|
||||
create_web_php_fpm_pool_config.delay(
|
||||
self.osuser.username).get()
|
||||
create_file_website_hierarchy.delay(
|
||||
self.osuser.username, fqdn).get()
|
||||
create_web_vhost_config.delay(
|
||||
self.osuser.username, fqdn, self.wildcard).get()
|
||||
enable_web_vhost.delay(fqdn).get()
|
||||
return super(Website, self).save(*args, **kwargs)
|
||||
|
||||
@transaction.atomic
|
||||
def delete(self, *args, **kwargs):
|
||||
fqdn = self.get_fqdn()
|
||||
osuser = self.osuser
|
||||
disable_web_vhost.delay(fqdn).get()
|
||||
delete_web_vhost_config.delay(fqdn).get()
|
||||
delete_file_website_hierarchy.delay(osuser.username, fqdn).get()
|
||||
deleted = super(Website, self).delete(*args, **kwargs)
|
||||
if not Website.objects.filter(osuser=osuser):
|
||||
delete_web_php_fpm_pool_config.delay(osuser.username).get()
|
||||
return deleted
|
21
gnuviechadmin/websites/urls.py
Normal file
21
gnuviechadmin/websites/urls.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
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,
|
||||
DeleteWebsite,
|
||||
)
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^(?P<package>\d+)/(?P<domain>[\w0-9.-]+)/create$',
|
||||
AddWebsite.as_view(), name='add_website'),
|
||||
url(r'^(?P<package>\d+)/(?P<domain>[\w0-9.-]+)/(?P<pk>\d+)/delete$',
|
||||
DeleteWebsite.as_view(), name='delete_website'),
|
||||
)
|
83
gnuviechadmin/websites/views.py
Normal file
83
gnuviechadmin/websites/views.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
"""
|
||||
This module defines views for website handling.
|
||||
|
||||
"""
|
||||
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,
|
||||
DeleteView,
|
||||
)
|
||||
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())
|
||||
|
||||
|
||||
class DeleteWebsite(
|
||||
HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, DeleteView
|
||||
):
|
||||
"""
|
||||
This view is used to delete websites in a customer hosting package.
|
||||
|
||||
"""
|
||||
context_object_name = 'website'
|
||||
model = Website
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DeleteWebsite, self).get_context_data(**kwargs)
|
||||
context.update({
|
||||
'customer': self.get_customer_object(),
|
||||
'hostingpackage': self.get_hosting_package(),
|
||||
})
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
return self.get_hosting_package().get_absolute_url()
|
4
gnuviechadmin/webtasks/__init__.py
Normal file
4
gnuviechadmin/webtasks/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
"""
|
||||
This module contains :py:mod:`webtasks.tasks`.
|
||||
|
||||
"""
|
82
gnuviechadmin/webtasks/tasks.py
Normal file
82
gnuviechadmin/webtasks/tasks.py
Normal file
|
@ -0,0 +1,82 @@
|
|||
"""
|
||||
This module defines Celery_ tasks to manage website configurations.
|
||||
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
from celery import shared_task
|
||||
|
||||
|
||||
@shared_task
|
||||
def create_web_vhost_config(username, sitename, wildcard):
|
||||
"""
|
||||
This task creates a virtual host configuration on an nginx web
|
||||
server.
|
||||
|
||||
:param str username: user who owns the site
|
||||
:param str sitename: site name
|
||||
:param boolean wildcard: designates whether this is website has a wildcard
|
||||
subdomain
|
||||
:return: :py:const:`True` if the creation finished successfully
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@shared_task
|
||||
def disable_web_vhost(sitename):
|
||||
"""
|
||||
This task disables a virtual host configuration on an nginx web server.
|
||||
|
||||
:param str sitename: site name
|
||||
:return: :py:const:`True` if the virtual host has been disabled
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@shared_task
|
||||
def enable_web_vhost(sitename):
|
||||
"""
|
||||
This task enables an existing virtual host configuration on an nginx web
|
||||
server.
|
||||
|
||||
:param str sitename: site name
|
||||
:return: :py:const:`True` if the virtual host has been enabled
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
|
||||
@shared_task
|
||||
def delete_web_vhost_config(sitename):
|
||||
"""
|
||||
This task removes a virtual host configuration on an nginx web server.
|
||||
|
||||
:param str sitename: site name
|
||||
:return: :py:const:`True` if the configuration has been deleted
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@shared_task
|
||||
def create_web_php_fpm_pool_config(username):
|
||||
"""
|
||||
This task creates a PHP FPM pool configuration.
|
||||
|
||||
:param str username: user name
|
||||
:return: :py:const:`True` if the creation finished successfully
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
|
||||
@shared_task
|
||||
def delete_web_php_fpm_pool_config(username):
|
||||
"""
|
||||
This task deletes a PHP FPM pool configuration.
|
||||
|
||||
:param str username: user name
|
||||
:return: :py:const:`True` if the pool has been deleted
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
Loading…
Reference in a new issue