2014-05-08 16:59:35 +00:00
|
|
|
import re
|
|
|
|
|
|
|
|
from django.core.exceptions import ValidationError
|
|
|
|
from django.db import models
|
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
|
|
|
|
from orchestra.core import validators, services
|
2014-10-24 10:16:46 +00:00
|
|
|
from orchestra.utils import tuple_setting_to_choices
|
2014-05-08 16:59:35 +00:00
|
|
|
from orchestra.utils.functional import cached
|
|
|
|
|
|
|
|
from . import settings
|
|
|
|
|
|
|
|
|
|
|
|
class Website(models.Model):
|
2014-11-27 19:17:26 +00:00
|
|
|
""" Models a web site, also known as virtual host """
|
2015-02-27 16:57:39 +00:00
|
|
|
name = models.CharField(_("name"), max_length=128,
|
2014-05-08 16:59:35 +00:00
|
|
|
validators=[validators.validate_name])
|
|
|
|
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
|
|
|
|
related_name='websites')
|
|
|
|
port = models.PositiveIntegerField(_("port"),
|
|
|
|
choices=settings.WEBSITES_PORT_CHOICES,
|
|
|
|
default=settings.WEBSITES_DEFAULT_PORT)
|
|
|
|
domains = models.ManyToManyField(settings.WEBSITES_DOMAIN_MODEL,
|
|
|
|
related_name='websites', verbose_name=_("domains"))
|
|
|
|
contents = models.ManyToManyField('webapps.WebApp', through='websites.Content')
|
2014-09-30 10:20:11 +00:00
|
|
|
is_active = models.BooleanField(_("active"), default=True)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
2015-02-27 16:57:39 +00:00
|
|
|
class Meta:
|
|
|
|
unique_together = ('name', 'account')
|
|
|
|
|
2014-05-08 16:59:35 +00:00
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def unique_name(self):
|
2015-02-27 16:57:39 +00:00
|
|
|
return settings.WEBSITES_UNIQUE_NAME_FORMAT % {
|
|
|
|
'id': self.id,
|
|
|
|
'pk': self.pk,
|
|
|
|
'account': self.account.username,
|
|
|
|
'port': self.port,
|
|
|
|
'name': self.name,
|
|
|
|
}
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def protocol(self):
|
|
|
|
if self.port == 80:
|
|
|
|
return 'http'
|
|
|
|
if self.port == 443:
|
|
|
|
return 'https'
|
|
|
|
raise TypeError('No protocol for port "%s"' % self.port)
|
2014-10-23 15:38:46 +00:00
|
|
|
|
2015-02-25 17:29:39 +00:00
|
|
|
@cached
|
|
|
|
def get_options(self):
|
|
|
|
return {
|
|
|
|
opt.name: opt.value for opt in self.options.all()
|
|
|
|
}
|
|
|
|
|
2014-10-23 15:38:46 +00:00
|
|
|
def get_absolute_url(self):
|
|
|
|
domain = self.domains.first()
|
|
|
|
if domain:
|
|
|
|
return '%s://%s' % (self.protocol, domain)
|
|
|
|
|
2015-03-02 10:37:25 +00:00
|
|
|
def get_www_log_context(self):
|
|
|
|
return {
|
2015-02-27 16:57:39 +00:00
|
|
|
'home': self.account.main_systemuser.get_home(),
|
|
|
|
'account': self.account.username,
|
2014-11-13 15:34:00 +00:00
|
|
|
'name': self.name,
|
2014-10-27 14:31:04 +00:00
|
|
|
'unique_name': self.unique_name
|
|
|
|
}
|
2015-03-02 10:37:25 +00:00
|
|
|
|
|
|
|
def get_www_access_log_path(self):
|
|
|
|
context = self.get_www_log_context()
|
|
|
|
path = settings.WEBSITES_WEBSITE_WWW_ACCESS_LOG_PATH % context
|
|
|
|
return path.replace('//', '/')
|
|
|
|
|
|
|
|
def get_www_error_log_path(self):
|
|
|
|
context = self.get_www_log_context()
|
|
|
|
path = settings.WEBSITES_WEBSITE_WWW_ERROR_LOG_PATH % context
|
|
|
|
return path.replace('//', '/')
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
class WebsiteOption(models.Model):
|
|
|
|
website = models.ForeignKey(Website, verbose_name=_("web site"),
|
|
|
|
related_name='options')
|
|
|
|
name = models.CharField(_("name"), max_length=128,
|
2014-10-24 10:16:46 +00:00
|
|
|
choices=tuple_setting_to_choices(settings.WEBSITES_OPTIONS))
|
2014-05-08 16:59:35 +00:00
|
|
|
value = models.CharField(_("value"), max_length=256)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
unique_together = ('website', 'name')
|
|
|
|
verbose_name = _("option")
|
|
|
|
verbose_name_plural = _("options")
|
|
|
|
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
""" validates name and value according to WEBSITES_WEBSITEOPTIONS """
|
2014-11-10 15:03:34 +00:00
|
|
|
regex = settings.WEBSITES_OPTIONS[self.name][-1]
|
2014-05-08 16:59:35 +00:00
|
|
|
if not re.match(regex, self.value):
|
2014-11-05 20:22:01 +00:00
|
|
|
raise ValidationError({
|
|
|
|
'value': ValidationError(_("'%(value)s' does not match %(regex)s."),
|
|
|
|
params={
|
|
|
|
'value': self.value,
|
|
|
|
'regex': regex
|
|
|
|
}),
|
|
|
|
})
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Content(models.Model):
|
|
|
|
webapp = models.ForeignKey('webapps.WebApp', verbose_name=_("web application"))
|
|
|
|
website = models.ForeignKey('websites.Website', verbose_name=_("web site"))
|
2014-10-21 16:13:18 +00:00
|
|
|
path = models.CharField(_("path"), max_length=256, blank=True,
|
|
|
|
validators=[validators.validate_url_path])
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
unique_together = ('website', 'path')
|
|
|
|
|
2014-10-14 13:50:19 +00:00
|
|
|
def __unicode__(self):
|
|
|
|
try:
|
|
|
|
return self.website.name + self.path
|
|
|
|
except Website.DoesNotExist:
|
|
|
|
return self.path
|
|
|
|
|
2014-05-08 16:59:35 +00:00
|
|
|
def clean(self):
|
|
|
|
if not self.path.startswith('/'):
|
|
|
|
self.path = '/' + self.path
|
2014-10-23 15:38:46 +00:00
|
|
|
|
|
|
|
def get_absolute_url(self):
|
|
|
|
domain = self.website.domains.first()
|
|
|
|
if domain:
|
|
|
|
return '%s://%s%s' % (self.website.protocol, domain, self.path)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
services.register(Website)
|