django-orchestra/orchestra/apps/websites/models.py

154 lines
5 KiB
Python
Raw Normal View History

2015-03-10 21:51:10 +00:00
import os
2014-05-08 16:59:35 +00:00
import re
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.functional import cached_property
2014-05-08 16:59:35 +00:00
from django.utils.translation import ugettext_lazy as _
from orchestra.core import validators, services
from orchestra.utils.functional import cached
from . import settings
from .directives import SiteDirective
2015-03-10 21:51:10 +00:00
from .utils import normurlpath
2014-05-08 16:59:35 +00:00
class Website(models.Model):
2014-11-27 19:17:26 +00:00
""" Models a web site, also known as virtual host """
2015-03-10 21:51:10 +00:00
HTTP = 'http'
HTTPS = 'https'
HTTP_AND_HTTPS = 'http/https'
HTTPS_ONLY = 'https-only'
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')
2015-03-10 21:51:10 +00:00
protocol = models.CharField(_("protocol"), max_length=16,
choices=settings.WEBSITES_PROTOCOL_CHOICES,
2015-03-10 22:27:32 +00:00
default=settings.WEBSITES_DEFAULT_PROTOCOL,
help_text=_("Select the protocol(s) for this website<br>"
"<tt>HTTPS only</tt> performs a redirection from <tt>http</tt> to <tt>https</tt>."))
2015-03-10 21:51:10 +00:00
# port = models.PositiveIntegerField(_("port"),
# choices=settings.WEBSITES_PORT_CHOICES,
# default=settings.WEBSITES_DEFAULT_PORT)
2014-05-08 16:59:35 +00:00
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
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-03-18 21:51:12 +00:00
context = self.get_settings_context()
return settings.WEBSITES_UNIQUE_NAME_FORMAT % context
def get_settings_context(self):
""" format settings strings """
return {
'id': self.id,
'pk': self.pk,
2015-03-18 21:51:12 +00:00
'home': self.get_user().get_home(),
'user': self.get_username(),
'group': self.get_groupname(),
'site_name': self.name,
2015-03-10 21:51:10 +00:00
'protocol': self.protocol,
}
2014-05-08 16:59:35 +00:00
2015-03-10 21:51:10 +00:00
def get_protocol(self):
if self.protocol in (self.HTTP, self.HTTP_AND_HTTPS):
return self.HTTP
return self.HTTPS
2014-10-23 15:38:46 +00:00
@cached
def get_directives(self):
2015-03-10 21:51:10 +00:00
directives = {}
for opt in self.directives.all():
try:
directives[opt.name].append(opt.value)
except KeyError:
directives[opt.name] = [opt.value]
return directives
2014-10-23 15:38:46 +00:00
def get_absolute_url(self):
domain = self.domains.first()
if domain:
2015-03-10 21:51:10 +00:00
return '%s://%s' % (self.get_protocol(), domain)
2014-10-23 15:38:46 +00:00
2015-03-18 21:51:12 +00:00
def get_user(self):
return self.account.main_systemuser
def get_username(self):
return self.get_user().username
def get_groupname(self):
return self.get_username()
2015-03-02 10:37:25 +00:00
def get_www_access_log_path(self):
2015-03-18 21:51:12 +00:00
context = self.get_settings_context()
2015-03-02 10:37:25 +00:00
path = settings.WEBSITES_WEBSITE_WWW_ACCESS_LOG_PATH % context
2015-03-10 21:51:10 +00:00
return os.path.normpath(path.replace('//', '/'))
2015-03-02 10:37:25 +00:00
def get_www_error_log_path(self):
2015-03-18 21:51:12 +00:00
context = self.get_settings_context()
2015-03-02 10:37:25 +00:00
path = settings.WEBSITES_WEBSITE_WWW_ERROR_LOG_PATH % context
2015-03-10 21:51:10 +00:00
return os.path.normpath(path.replace('//', '/'))
2014-05-08 16:59:35 +00:00
2015-03-04 21:06:16 +00:00
2015-03-18 21:51:12 +00:00
class WebsiteDirective(models.Model):
2014-05-08 16:59:35 +00:00
website = models.ForeignKey(Website, verbose_name=_("web site"),
related_name='directives')
2014-05-08 16:59:35 +00:00
name = models.CharField(_("name"), max_length=128,
choices=SiteDirective.get_plugin_choices())
2014-05-08 16:59:35 +00:00
value = models.CharField(_("value"), max_length=256)
def __unicode__(self):
return self.name
@cached_property
def directive_class(self):
return SiteDirective.get_plugin(self.name)
@cached_property
def directive_instance(self):
""" Per request lived directive instance """
return self.directive_class()
2014-05-08 16:59:35 +00:00
def clean(self):
self.directive_instance.validate(self)
2014-05-08 16:59:35 +00:00
class Content(models.Model):
# related_name is content_set to differentiate between website.content -> webapp
webapp = models.ForeignKey('webapps.WebApp', verbose_name=_("web application"))
website = models.ForeignKey('websites.Website', verbose_name=_("web site"))
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')
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):
2015-03-23 15:36:51 +00:00
# TODO do it on the field?
2015-03-10 21:51:10 +00:00
self.path = normurlpath(self.path)
2014-10-23 15:38:46 +00:00
def get_absolute_url(self):
domain = self.website.domains.first()
if domain:
2015-03-10 21:51:10 +00:00
return '%s://%s%s' % (self.website.get_protocol(), domain, self.path)
2014-05-08 16:59:35 +00:00
services.register(Website)