Replace cached, IPy and cmp_key for python3 standard library
This commit is contained in:
parent
b5a13af46c
commit
4173d7de27
3
TODO.md
3
TODO.md
|
@ -417,8 +417,5 @@ mkhomedir_helper or create ssh homes with bash.rc and such
|
||||||
# validate saas setting allow_custom_url check that websites have a related declared directive
|
# validate saas setting allow_custom_url check that websites have a related declared directive
|
||||||
# warnings if some plugins are disabled, like make routes red
|
# warnings if some plugins are disabled, like make routes red
|
||||||
|
|
||||||
# replace cached by https://docs.python.org/3/library/functools.html#functools.lru_cache
|
|
||||||
# replace IPy by https://docs.python.org/3/library/ipaddress.html#module-ipaddress
|
|
||||||
# replace show emails by https://docs.python.org/3/library/email.contentmanager.html#module-email.contentmanager
|
# replace show emails by https://docs.python.org/3/library/email.contentmanager.html#module-email.contentmanager
|
||||||
# https://docs.python.org/3/library/functools.html#functools.cmp_to_key
|
|
||||||
# tzinfo=datetime.timezone.utc
|
# tzinfo=datetime.timezone.utc
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.core.validators import ValidationError, RegexValidator
|
from django.core.validators import ValidationError, RegexValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -14,7 +15,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from orchestra.contrib.accounts.models import Account
|
from orchestra.contrib.accounts.models import Account
|
||||||
from orchestra.contrib.contacts.models import Contact
|
from orchestra.contrib.contacts.models import Contact
|
||||||
from orchestra.core import validators
|
from orchestra.core import validators
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.html import html_to_pdf
|
from orchestra.utils.html import html_to_pdf
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -319,7 +319,7 @@ class Bill(models.Model):
|
||||||
self.number = self.get_number()
|
self.number = self.get_number()
|
||||||
super(Bill, self).save(*args, **kwargs)
|
super(Bill, self).save(*args, **kwargs)
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def compute_subtotals(self):
|
def compute_subtotals(self):
|
||||||
subtotals = {}
|
subtotals = {}
|
||||||
lines = self.lines.annotate(totals=F('subtotal') + Sum(Coalesce('sublines__total', 0)))
|
lines = self.lines.annotate(totals=F('subtotal') + Sum(Coalesce('sublines__total', 0)))
|
||||||
|
@ -333,21 +333,21 @@ class Bill(models.Model):
|
||||||
result[tax] = (subtotal, round(tax/100*subtotal, 2))
|
result[tax] = (subtotal, round(tax/100*subtotal, 2))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def compute_base(self):
|
def compute_base(self):
|
||||||
bases = self.lines.annotate(
|
bases = self.lines.annotate(
|
||||||
bases=F('subtotal') + Sum(Coalesce('sublines__total', 0))
|
bases=F('subtotal') + Sum(Coalesce('sublines__total', 0))
|
||||||
)
|
)
|
||||||
return round(bases.aggregate(Sum('bases'))['bases__sum'] or 0, 2)
|
return round(bases.aggregate(Sum('bases'))['bases__sum'] or 0, 2)
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def compute_tax(self):
|
def compute_tax(self):
|
||||||
taxes = self.lines.annotate(
|
taxes = self.lines.annotate(
|
||||||
taxes=(F('subtotal') + Coalesce(Sum('sublines__total'), 0)) * (F('tax')/100)
|
taxes=(F('subtotal') + Coalesce(Sum('sublines__total'), 0)) * (F('tax')/100)
|
||||||
)
|
)
|
||||||
return round(taxes.aggregate(Sum('taxes'))['taxes__sum'] or 0, 2)
|
return round(taxes.aggregate(Sum('taxes'))['taxes__sum'] or 0, 2)
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def compute_total(self):
|
def compute_total(self):
|
||||||
if 'lines' in getattr(self, '_prefetched_objects_cache', ()):
|
if 'lines' in getattr(self, '_prefetched_objects_cache', ()):
|
||||||
total = 0
|
total = 0
|
||||||
|
@ -430,7 +430,7 @@ class BillLine(models.Model):
|
||||||
return ini
|
return ini
|
||||||
return "{ini} / {end}".format(ini=ini, end=end)
|
return "{ini} / {end}".format(ini=ini, end=end)
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def compute_total(self):
|
def compute_total(self):
|
||||||
total = self.subtotal or 0
|
total = self.subtotal or 0
|
||||||
if hasattr(self, 'subline_total'):
|
if hasattr(self, 'subline_total'):
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
from dateutil import relativedelta
|
from dateutil import relativedelta
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from orchestra import plugins
|
from orchestra import plugins
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
|
@ -20,7 +20,7 @@ class PaymentMethod(plugins.Plugin):
|
||||||
state_help = {}
|
state_help = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_plugins(cls):
|
def get_plugins(cls):
|
||||||
plugins = []
|
plugins = []
|
||||||
for cls in settings.PAYMENTS_ENABLED_METHODS:
|
for cls in settings.PAYMENTS_ENABLED_METHODS:
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.core.validators import ValidationError
|
from django.core.validators import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
@ -6,7 +8,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core.validators import validate_name
|
from orchestra.core.validators import validate_name
|
||||||
from orchestra.models import queryset
|
from orchestra.models import queryset
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -84,12 +85,12 @@ class Rate(models.Model):
|
||||||
return "{}-{}".format(str(self.price), self.quantity)
|
return "{}-{}".format(str(self.price), self.quantity)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_methods(cls):
|
def get_methods(cls):
|
||||||
return dict((method, import_class(method)) for method in settings.PLANS_RATE_METHODS)
|
return dict((method, import_class(method)) for method in settings.PLANS_RATE_METHODS)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_choices(cls):
|
def get_choices(cls):
|
||||||
choices = []
|
choices = []
|
||||||
for name, method in cls.get_methods().items():
|
for name, method in cls.get_methods().items():
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from functools import lru_cache
|
||||||
from urllib.parse import parse_qs
|
from urllib.parse import parse_qs
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
@ -19,7 +20,6 @@ from orchestra.admin.utils import insertattr, get_modeladmin, admin_link, admin_
|
||||||
from orchestra.contrib.orchestration.models import Route
|
from orchestra.contrib.orchestration.models import Route
|
||||||
from orchestra.core import services
|
from orchestra.core import services
|
||||||
from orchestra.utils import db, sys
|
from orchestra.utils import db, sys
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
|
|
||||||
from .actions import run_monitor, show_history
|
from .actions import run_monitor, show_history
|
||||||
from .api import history_data
|
from .api import history_data
|
||||||
|
@ -240,7 +240,7 @@ def resource_inline_factory(resources):
|
||||||
def total_form_count(self, resources=resources):
|
def total_form_count(self, resources=resources):
|
||||||
return len(resources)
|
return len(resources)
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
""" Filter disabled resources """
|
""" Filter disabled resources """
|
||||||
queryset = super(ResourceInlineFormSet, self).get_queryset()
|
queryset = super(ResourceInlineFormSet, self).get_queryset()
|
||||||
|
|
|
@ -33,7 +33,8 @@ class MoodleMuBackend(ServiceController):
|
||||||
$wwwroot = "https://{$site}-courses.pangea.org";
|
$wwwroot = "https://{$site}-courses.pangea.org";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$CFG->prefix = "${site}_";
|
$prefix = str_replace('-', '_', $site);
|
||||||
|
$CFG->prefix = "${prefix}_";
|
||||||
$CFG->wwwroot = $wwwroot;
|
$CFG->wwwroot = $wwwroot;
|
||||||
$CFG->dataroot = "/home/pangea/moodledata/{$site}/";
|
$CFG->dataroot = "/home/pangea/moodledata/{$site}/";
|
||||||
"""
|
"""
|
||||||
|
@ -43,6 +44,9 @@ class MoodleMuBackend(ServiceController):
|
||||||
|
|
||||||
def save(self, webapp):
|
def save(self, webapp):
|
||||||
context = self.get_context(webapp)
|
context = self.get_context(webapp)
|
||||||
|
self.delete_site_map(context)
|
||||||
|
if context['custom_url']:
|
||||||
|
self.insert_site_map(context)
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
mkdir -p %(moodledata_path)s
|
mkdir -p %(moodledata_path)s
|
||||||
chown %(user)s:%(user)s %(moodledata_path)s
|
chown %(user)s:%(user)s %(moodledata_path)s
|
||||||
|
@ -64,9 +68,9 @@ class MoodleMuBackend(ServiceController):
|
||||||
--host="%(db_host)s" \\
|
--host="%(db_host)s" \\
|
||||||
--user="%(db_user)s" \\
|
--user="%(db_user)s" \\
|
||||||
--password="%(db_pass)s" \\
|
--password="%(db_pass)s" \\
|
||||||
--execute='UPDATE %(site_name)s_user
|
--execute='UPDATE %(db_prefix)s_user
|
||||||
SET password=MD5("%(password)s")
|
SET password=MD5("%(password)s")
|
||||||
WHERE username="admin"' \\
|
WHERE username="admin";' \\
|
||||||
%(db_name)s
|
%(db_name)s
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
@ -83,9 +87,6 @@ class MoodleMuBackend(ServiceController):
|
||||||
EOF
|
EOF
|
||||||
fi""") % context
|
fi""") % context
|
||||||
)
|
)
|
||||||
self.delete_site_map(context)
|
|
||||||
if context['custom_url']:
|
|
||||||
self.insert_site_map(context)
|
|
||||||
|
|
||||||
def delete_site_map(self, context):
|
def delete_site_map(self, context):
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
|
@ -105,7 +106,7 @@ class MoodleMuBackend(ServiceController):
|
||||||
context = self.get_context(saas)
|
context = self.get_context(saas)
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
rm -rf %(moodledata_path)s
|
rm -rf %(moodledata_path)s
|
||||||
# Delete tables with prefix %(site_name)s
|
# Delete tables with prefix %(db_prefix)s
|
||||||
mysql -Nrs \\
|
mysql -Nrs \\
|
||||||
--host="%(db_host)s" \\
|
--host="%(db_host)s" \\
|
||||||
--user="%(db_user)s" \\
|
--user="%(db_user)s" \\
|
||||||
|
@ -114,7 +115,7 @@ class MoodleMuBackend(ServiceController):
|
||||||
SET @tbls = (SELECT GROUP_CONCAT(TABLE_NAME)
|
SET @tbls = (SELECT GROUP_CONCAT(TABLE_NAME)
|
||||||
FROM information_schema.TABLES
|
FROM information_schema.TABLES
|
||||||
WHERE TABLE_SCHEMA = "%(db_name)s"
|
WHERE TABLE_SCHEMA = "%(db_name)s"
|
||||||
AND TABLE_NAME LIKE "%(site_name)s_%%");
|
AND TABLE_NAME LIKE "%(db_prefix)s_%%");
|
||||||
SET @delStmt = CONCAT("DROP TABLE ", @tbls);
|
SET @delStmt = CONCAT("DROP TABLE ", @tbls);
|
||||||
-- SELECT @delStmt;
|
-- SELECT @delStmt;
|
||||||
PREPARE stmt FROM @delStmt;
|
PREPARE stmt FROM @delStmt;
|
||||||
|
@ -146,9 +147,10 @@ class MoodleMuBackend(ServiceController):
|
||||||
'db_pass': settings.SAAS_MOODLE_DB_PASS,
|
'db_pass': settings.SAAS_MOODLE_DB_PASS,
|
||||||
'db_name': settings.SAAS_MOODLE_DB_NAME,
|
'db_name': settings.SAAS_MOODLE_DB_NAME,
|
||||||
'db_host': settings.SAAS_MOODLE_DB_HOST,
|
'db_host': settings.SAAS_MOODLE_DB_HOST,
|
||||||
|
'db_prefix': saas.name.replace('-', '_'),
|
||||||
'email': saas.account.email,
|
'email': saas.account.email,
|
||||||
'password': getattr(saas, 'password', None),
|
'password': getattr(saas, 'password', None),
|
||||||
'custom_url': saas.custom_url,
|
'custom_url': saas.custom_url.rstrip('/'),
|
||||||
'custom_domain': urlparse(saas.custom_url).netloc if saas.custom_url else None,
|
'custom_domain': urlparse(saas.custom_url).netloc if saas.custom_url else None,
|
||||||
}
|
}
|
||||||
context.update({
|
context.update({
|
||||||
|
|
|
@ -24,8 +24,8 @@ class SaaS(models.Model):
|
||||||
service = models.CharField(_("service"), max_length=32,
|
service = models.CharField(_("service"), max_length=32,
|
||||||
choices=SoftwareService.get_choices())
|
choices=SoftwareService.get_choices())
|
||||||
name = models.CharField(_("Name"), max_length=64,
|
name = models.CharField(_("Name"), max_length=64,
|
||||||
help_text=_("Required. 64 characters or fewer. Letters, digits and ./-/_ only."),
|
help_text=_("Required. 64 characters or fewer. Letters, digits and ./- only."),
|
||||||
validators=[validators.validate_username])
|
validators=[validators.validate_hostname])
|
||||||
account = models.ForeignKey('accounts.Account', verbose_name=_("account"),
|
account = models.ForeignKey('accounts.Account', verbose_name=_("account"),
|
||||||
related_name='saas')
|
related_name='saas')
|
||||||
is_active = models.BooleanField(_("active"), default=True,
|
is_active = models.BooleanField(_("active"), default=True,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from functools import lru_cache
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
||||||
|
@ -8,7 +9,6 @@ from orchestra.contrib.databases.models import Database, DatabaseUser
|
||||||
from orchestra.contrib.orchestration import Operation
|
from orchestra.contrib.orchestration import Operation
|
||||||
from orchestra.contrib.websites.models import Website, WebsiteDirective
|
from orchestra.contrib.websites.models import Website, WebsiteDirective
|
||||||
from orchestra.utils.apps import isinstalled
|
from orchestra.utils.apps import isinstalled
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from . import helpers
|
from . import helpers
|
||||||
|
@ -33,7 +33,7 @@ class SoftwareService(plugins.Plugin):
|
||||||
allow_custom_url = False
|
allow_custom_url = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_plugins(cls):
|
def get_plugins(cls):
|
||||||
plugins = []
|
plugins = []
|
||||||
for cls in settings.SAAS_ENABLED_SERVICES:
|
for cls in settings.SAAS_ENABLED_SERVICES:
|
||||||
|
@ -153,7 +153,7 @@ class DBSoftwareService(SoftwareService):
|
||||||
def get_db_user(self):
|
def get_db_user(self):
|
||||||
return self.db_user
|
return self.db_user
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_account(self):
|
def get_account(self):
|
||||||
account_model = self.instance._meta.get_field_by_name('account')[0]
|
account_model = self.instance._meta.get_field_by_name('account')[0]
|
||||||
return account_model.rel.to.objects.get_main()
|
return account_model.rel.to.objects.get_main()
|
||||||
|
|
|
@ -2,6 +2,7 @@ import calendar
|
||||||
import datetime
|
import datetime
|
||||||
import decimal
|
import decimal
|
||||||
import math
|
import math
|
||||||
|
from functools import cmp_to_key
|
||||||
|
|
||||||
from dateutil import relativedelta
|
from dateutil import relativedelta
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
@ -11,7 +12,7 @@ from django.utils.translation import ugettext, ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra import plugins
|
from orchestra import plugins
|
||||||
from orchestra.utils.humanize import text2int
|
from orchestra.utils.humanize import text2int
|
||||||
from orchestra.utils.python import AttrDict, cmp_to_key, format_exception
|
from orchestra.utils.python import AttrDict, format_exception
|
||||||
|
|
||||||
from . import settings, helpers
|
from . import settings, helpers
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import datetime
|
import datetime
|
||||||
import decimal
|
import decimal
|
||||||
|
from functools import cmp_to_key
|
||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from orchestra.contrib.systemusers.models import SystemUser
|
from orchestra.contrib.systemusers.models import SystemUser
|
||||||
from orchestra.contrib.plans.models import Plan
|
from orchestra.contrib.plans.models import Plan
|
||||||
from orchestra.utils.python import cmp_to_key
|
|
||||||
from orchestra.utils.tests import BaseTestCase
|
from orchestra.utils.tests import BaseTestCase
|
||||||
|
|
||||||
from .. import helpers
|
from .. import helpers
|
||||||
|
|
|
@ -31,6 +31,7 @@ class UNIXUserBackend(ServiceController):
|
||||||
groups = ','.join(self.get_groups(user))
|
groups = ','.join(self.get_groups(user))
|
||||||
context['groups_arg'] = '--groups %s' % groups if groups else ''
|
context['groups_arg'] = '--groups %s' % groups if groups else ''
|
||||||
# TODO userd add will fail if %(user)s group already exists
|
# TODO userd add will fail if %(user)s group already exists
|
||||||
|
# TODO mkhomedir_helper
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
# Update/create user state for %(user)s
|
# Update/create user state for %(user)s
|
||||||
if id %(user)s ; then
|
if id %(user)s ; then
|
||||||
|
|
|
@ -7,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from jsonfield import JSONField
|
from jsonfield import JSONField
|
||||||
|
|
||||||
from orchestra.core import validators
|
from orchestra.core import validators
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
from .fields import VirtualDatabaseRelation, VirtualDatabaseUserRelation
|
from .fields import VirtualDatabaseRelation, VirtualDatabaseUserRelation
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import re
|
import re
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.plugins import Plugin
|
from orchestra.plugins import Plugin
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -20,7 +20,7 @@ class AppOption(Plugin):
|
||||||
comma_separated = False
|
comma_separated = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_plugins(cls):
|
def get_plugins(cls):
|
||||||
plugins = []
|
plugins = []
|
||||||
for cls in settings.WEBAPPS_ENABLED_OPTIONS:
|
for cls in settings.WEBAPPS_ENABLED_OPTIONS:
|
||||||
|
@ -28,7 +28,7 @@ class AppOption(Plugin):
|
||||||
return plugins
|
return plugins
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_option_groups(cls):
|
def get_option_groups(cls):
|
||||||
groups = {}
|
groups = {}
|
||||||
for opt in cls.get_plugins():
|
for opt in cls.get_plugins():
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra import plugins
|
from orchestra import plugins
|
||||||
from orchestra.plugins.forms import PluginDataForm
|
from orchestra.plugins.forms import PluginDataForm
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from .. import settings
|
from .. import settings
|
||||||
|
@ -22,7 +23,7 @@ class AppType(plugins.Plugin):
|
||||||
# TODO generic name like 'execution' ?
|
# TODO generic name like 'execution' ?
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_plugins(cls):
|
def get_plugins(cls):
|
||||||
plugins = []
|
plugins = []
|
||||||
for cls in settings.WEBAPPS_TYPES:
|
for cls in settings.WEBAPPS_TYPES:
|
||||||
|
@ -38,7 +39,7 @@ class AppType(plugins.Plugin):
|
||||||
})
|
})
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_group_options(cls):
|
def get_group_options(cls):
|
||||||
""" Get enabled options based on cls.option_groups """
|
""" Get enabled options based on cls.option_groups """
|
||||||
groups = AppOption.get_option_groups()
|
groups = AppOption.get_option_groups()
|
||||||
|
@ -54,7 +55,7 @@ class AppType(plugins.Plugin):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_group_options_choices(cls):
|
def get_group_options_choices(cls):
|
||||||
""" Generates grouped choices ready to use in Field.choices """
|
""" Generates grouped choices ready to use in Field.choices """
|
||||||
# generators can not be @cached
|
# generators can not be @lru_cache
|
||||||
yield (None, '-------')
|
yield (None, '-------')
|
||||||
for group, options in cls.get_group_options():
|
for group, options in cls.get_group_options():
|
||||||
if group is None:
|
if group is None:
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import os
|
import os
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from orchestra.plugins.forms import PluginDataForm
|
from orchestra.plugins.forms import PluginDataForm
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
|
|
||||||
from .. import settings, utils
|
from .. import settings, utils
|
||||||
from ..options import AppOption
|
from ..options import AppOption
|
||||||
|
@ -58,7 +58,7 @@ class PHPApp(AppType):
|
||||||
def get_detail(self):
|
def get_detail(self):
|
||||||
return self.instance.data.get('php_version', '')
|
return self.instance.data.get('php_version', '')
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_options(self, merge=settings.WEBAPPS_MERGE_PHP_WEBAPPS):
|
def get_options(self, merge=settings.WEBAPPS_MERGE_PHP_WEBAPPS):
|
||||||
""" adapter to webapp.get_options that performs merging of PHP options """
|
""" adapter to webapp.get_options that performs merging of PHP options """
|
||||||
kwargs = {
|
kwargs = {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import re
|
import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.plugins import Plugin
|
from orchestra.plugins import Plugin
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -24,7 +24,7 @@ class SiteDirective(Plugin):
|
||||||
unique_location = False
|
unique_location = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_plugins(cls):
|
def get_plugins(cls):
|
||||||
plugins = []
|
plugins = []
|
||||||
for cls in settings.WEBSITES_ENABLED_DIRECTIVES:
|
for cls in settings.WEBSITES_ENABLED_DIRECTIVES:
|
||||||
|
@ -32,7 +32,7 @@ class SiteDirective(Plugin):
|
||||||
return plugins
|
return plugins
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_option_groups(cls):
|
def get_option_groups(cls):
|
||||||
groups = {}
|
groups = {}
|
||||||
for opt in cls.get_plugins():
|
for opt in cls.get_plugins():
|
||||||
|
@ -45,7 +45,7 @@ class SiteDirective(Plugin):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_choices(cls):
|
def get_choices(cls):
|
||||||
""" Generates grouped choices ready to use in Field.choices """
|
""" Generates grouped choices ready to use in Field.choices """
|
||||||
# generators can not be @cached
|
# generators can not be @lru_cache()
|
||||||
yield (None, '-------')
|
yield (None, '-------')
|
||||||
options = cls.get_option_groups()
|
options = cls.get_option_groups()
|
||||||
for option in options.pop(None, ()):
|
for option in options.pop(None, ()):
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import os
|
import os
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import validators
|
from orchestra.core import validators
|
||||||
from orchestra.utils.functional import cached
|
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
from .directives import SiteDirective
|
from .directives import SiteDirective
|
||||||
|
@ -72,7 +72,7 @@ class Website(models.Model):
|
||||||
return self.HTTP
|
return self.HTTP
|
||||||
return self.HTTPS
|
return self.HTTPS
|
||||||
|
|
||||||
@cached
|
@lru_cache()
|
||||||
def get_directives(self):
|
def get_directives(self):
|
||||||
directives = OrderedDict()
|
directives = OrderedDict()
|
||||||
for opt in self.directives.all().order_by('name', 'value'):
|
for opt in self.directives.all().order_by('name', 'value'):
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from ipaddress import ip_address
|
||||||
|
|
||||||
import phonenumbers
|
import phonenumbers
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from IPy import IP
|
|
||||||
|
|
||||||
from ..utils.python import import_class
|
from ..utils.python import import_class
|
||||||
|
|
||||||
|
@ -40,28 +40,28 @@ def all_valid(*args):
|
||||||
def validate_ipv4_address(value):
|
def validate_ipv4_address(value):
|
||||||
msg = _("Not a valid IPv4 address")
|
msg = _("Not a valid IPv4 address")
|
||||||
try:
|
try:
|
||||||
ip = IP(value)
|
ip = ip_address(value)
|
||||||
except:
|
except ValueError:
|
||||||
raise ValidationError(msg)
|
raise ValidationError(msg)
|
||||||
if ip.version() != 4:
|
if ip.version != 4:
|
||||||
raise ValidationError(msg)
|
raise ValidationError(msg)
|
||||||
|
|
||||||
|
|
||||||
def validate_ipv6_address(value):
|
def validate_ipv6_address(value):
|
||||||
msg = _("Not a valid IPv6 address")
|
msg = _("Not a valid IPv6 address")
|
||||||
try:
|
try:
|
||||||
ip = IP(value)
|
ip = ip_address(value)
|
||||||
except:
|
except ValueError:
|
||||||
raise ValidationError(msg)
|
raise ValidationError(msg)
|
||||||
if ip.version() != 6:
|
if ip.version != 6:
|
||||||
raise ValidationError(msg)
|
raise ValidationError(msg)
|
||||||
|
|
||||||
|
|
||||||
def validate_ip_address(value):
|
def validate_ip_address(value):
|
||||||
msg = _("Not a valid IP address")
|
msg = _("Not a valid IP address")
|
||||||
try:
|
try:
|
||||||
IP(value)
|
ip_address(value)
|
||||||
except:
|
except ValueError:
|
||||||
raise ValidationError(msg)
|
raise ValidationError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ from os import path
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from orchestra.utils.paths import get_site_dir, get_orchestra_dir
|
from orchestra.contrib.settings import Setting, parser as settings_parser
|
||||||
|
from orchestra.utils.paths import get_site_dir, get_orchestra_dir, get_project_dir
|
||||||
from orchestra.utils.sys import run, check_root
|
from orchestra.utils.sys import run, check_root
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ class Command(BaseCommand):
|
||||||
'username': options.get('username'),
|
'username': options.get('username'),
|
||||||
'bin_path': path.join(get_orchestra_dir(), 'bin'),
|
'bin_path': path.join(get_orchestra_dir(), 'bin'),
|
||||||
'processes': options.get('processes'),
|
'processes': options.get('processes'),
|
||||||
|
'settings': path.join(get_project_dir(), 'settings.py')
|
||||||
}
|
}
|
||||||
|
|
||||||
celery_config = textwrap.dedent("""\
|
celery_config = textwrap.dedent("""\
|
||||||
|
@ -103,3 +105,37 @@ class Command(BaseCommand):
|
||||||
}"""
|
}"""
|
||||||
)
|
)
|
||||||
run("echo '%s' > /etc/logrotate.d/celeryd" % rotate)
|
run("echo '%s' > /etc/logrotate.d/celeryd" % rotate)
|
||||||
|
|
||||||
|
changes = {}
|
||||||
|
if Setting.settings['TASKS_BACKEND'].value != 'celery':
|
||||||
|
changes['TASKS_BACKEND'] = 'celery'
|
||||||
|
if Setting.settings['ORCHESTRA_START_SERVICES'].value == Setting.settings['ORCHESTRA_START_SERVICES'].default:
|
||||||
|
changes['ORCHESTRA_START_SERVICES'] = settings_parser.serialize(
|
||||||
|
(
|
||||||
|
'postgresql',
|
||||||
|
'celeryevcam',
|
||||||
|
'celeryd',
|
||||||
|
'celerybeat',
|
||||||
|
('uwsgi', 'nginx'),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if Setting.settings['ORCHESTRA_RESTART_SERVICES'].value == Setting.settings['ORCHESTRA_RESTART_SERVICES'].default:
|
||||||
|
changes['ORCHESTRA_RESTART_SERVICES'] = settings_parser.serialize(
|
||||||
|
(
|
||||||
|
'celeryd',
|
||||||
|
'celerybeat',
|
||||||
|
'uwsgi',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if Setting.settings['ORCHESTRA_STOP_SERVICES'].value == Setting.settings['ORCHESTRA_STOP_SERVICES'].default:
|
||||||
|
changes['ORCHESTRA_STOP_SERVICES'] = settings_parser.serialize(
|
||||||
|
(
|
||||||
|
('uwsgi', 'nginx'),
|
||||||
|
'celerybeat',
|
||||||
|
'celeryd',
|
||||||
|
'celeryevcam',
|
||||||
|
'postgresql'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if changes:
|
||||||
|
settings_parser.apply(changes)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import os
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from orchestra.contrib.settings import Setting, parser as settings_parser
|
||||||
from orchestra.utils.paths import get_site_dir
|
from orchestra.utils.paths import get_site_dir
|
||||||
from orchestra.utils.sys import run, check_non_root
|
from orchestra.utils.sys import run, check_non_root
|
||||||
|
|
||||||
|
@ -24,3 +25,16 @@ class Command(BaseCommand):
|
||||||
content += "\n* * * * * %(orchestra_beat)s %(site_dir)s/manage.py" % context
|
content += "\n* * * * * %(orchestra_beat)s %(site_dir)s/manage.py" % context
|
||||||
context['content'] = content
|
context['content'] = content
|
||||||
run("cat << EOF | crontab\n%(content)s\nEOF" % context, display=True)
|
run("cat << EOF | crontab\n%(content)s\nEOF" % context, display=True)
|
||||||
|
|
||||||
|
# Configrue settings to use threaded task backend
|
||||||
|
changes = {}
|
||||||
|
if Setting.settings['TASKS_BACKEND'].value == 'celery':
|
||||||
|
changes['TASKS_BACKEND'] = settings_parser.Remove()
|
||||||
|
if 'celeryd' in Setting.settings['ORCHESTRA_START_SERVICES'].value:
|
||||||
|
changes['ORCHESTRA_START_SERVICES'] = settings_parser.Remove()
|
||||||
|
if 'celeryd' in Setting.settings['ORCHESTRA_RESTART_SERVICES'].value:
|
||||||
|
changes['ORCHESTRA_RESTART_SERVICES'] = settings_parser.Remove()
|
||||||
|
if 'celeryd' in Setting.settings['ORCHESTRA_STOP_SERVICES'].value:
|
||||||
|
changes['ORCHESTRA_STOP_SERVICES'] = settings_parser.Remove()
|
||||||
|
if changes:
|
||||||
|
settings_parser.apply(changes)
|
||||||
|
|
|
@ -48,14 +48,12 @@ class Command(BaseCommand):
|
||||||
help = 'Setup PostgreSQL database.'
|
help = 'Setup PostgreSQL database.'
|
||||||
|
|
||||||
def run_postgres(self, cmd, *args, **kwargs):
|
def run_postgres(self, cmd, *args, **kwargs):
|
||||||
return run('su postgres -c "psql -c \\"%s\\""' % cmd, *args, display=True, **kwargs)
|
return run('su postgres -c "psql -c \\"%s\\""' % cmd, *args, **kwargs)
|
||||||
|
|
||||||
@check_root
|
@check_root
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
interactive = options.get('interactive')
|
interactive = options.get('interactive')
|
||||||
db_password = options.get('db_password')
|
db_password = options.get('db_password')
|
||||||
print(db_password)
|
|
||||||
print(type(db_password))
|
|
||||||
context = {
|
context = {
|
||||||
'db_name': options.get('db_name'),
|
'db_name': options.get('db_name'),
|
||||||
'db_user': options.get('db_user'),
|
'db_user': options.get('db_user'),
|
||||||
|
@ -76,11 +74,11 @@ class Command(BaseCommand):
|
||||||
"please provide a password [%(default_db_password)s]: " % context)
|
"please provide a password [%(default_db_password)s]: " % context)
|
||||||
context['db_password'] = input(msg) or context['default_db_password']
|
context['db_password'] = input(msg) or context['default_db_password']
|
||||||
self.run_postgres(alter_user % context)
|
self.run_postgres(alter_user % context)
|
||||||
msg = "Updated Postgres user '%(db_user)s' password '%(db_password)s'"
|
msg = "Updated Postgres user '%(db_user)s' password: '%(db_password)s'"
|
||||||
self.stdout.write(msg % context)
|
self.stdout.write(msg % context)
|
||||||
elif db_password:
|
elif db_password:
|
||||||
self.run_postgres(alter_user % context)
|
self.run_postgres(alter_user % context)
|
||||||
msg = "Updated Postgres user '%(db_user)s' password '%(db_password)s'"
|
msg = "Updated Postgres user '%(db_user)s' password: '%(db_password)s'"
|
||||||
self.stdout.write(msg % context)
|
self.stdout.write(msg % context)
|
||||||
else:
|
else:
|
||||||
raise CommandError("Postgres user '%(db_user)s' already exists and "
|
raise CommandError("Postgres user '%(db_user)s' already exists and "
|
||||||
|
@ -90,13 +88,6 @@ class Command(BaseCommand):
|
||||||
self.stdout.write(msg % context)
|
self.stdout.write(msg % context)
|
||||||
self.run_postgres(create_database % context, valid_codes=(0,1))
|
self.run_postgres(create_database % context, valid_codes=(0,1))
|
||||||
|
|
||||||
# run(textwrap.dedent("""\
|
|
||||||
# su postgres -c "psql -c \\"CREATE USER %(db_user)s PASSWORD '%(db_password)s';\\"" || {
|
|
||||||
# su postgres -c "psql -c \\"ALTER USER %(db_user)s WITH PASSWORD '%(db_password)s';\\""
|
|
||||||
# }
|
|
||||||
# su postgres -c "psql -c \\"CREATE DATABASE %(db_name)s OWNER %(db_user)s;\\""\
|
|
||||||
# """) % context, valid_codes=(0,1)
|
|
||||||
# )
|
|
||||||
context.update({
|
context.update({
|
||||||
'settings': os.path.join(get_project_dir(), 'settings.py')
|
'settings': os.path.join(get_project_dir(), 'settings.py')
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
def cached(func):
|
def cached(func):
|
||||||
""" caches func return value """
|
"""
|
||||||
|
DEPRECATED in favour of lru_cahce
|
||||||
|
caches func return value
|
||||||
|
"""
|
||||||
def cached_func(self, *args, **kwargs):
|
def cached_func(self, *args, **kwargs):
|
||||||
# id(self) prevents sharing within subclasses
|
# id(self) prevents sharing within subclasses
|
||||||
attr = '_cached_%s_%i' % (func.__name__, id(self))
|
attr = '_cached_%s_%i' % (func.__name__, id(self))
|
||||||
|
|
|
@ -100,26 +100,6 @@ class CaptureStdout(list):
|
||||||
sys.stdout = self._stdout
|
sys.stdout = self._stdout
|
||||||
|
|
||||||
|
|
||||||
def cmp_to_key(mycmp):
|
|
||||||
'Convert a cmp= function into a key= function'
|
|
||||||
class K(object):
|
|
||||||
def __init__(self, obj, *args):
|
|
||||||
self.obj = obj
|
|
||||||
def __lt__(self, other):
|
|
||||||
return mycmp(self.obj, other.obj) < 0
|
|
||||||
def __gt__(self, other):
|
|
||||||
return mycmp(self.obj, other.obj) > 0
|
|
||||||
def __eq__(self, other):
|
|
||||||
return mycmp(self.obj, other.obj) == 0
|
|
||||||
def __le__(self, other):
|
|
||||||
return mycmp(self.obj, other.obj) <= 0
|
|
||||||
def __ge__(self, other):
|
|
||||||
return mycmp(self.obj, other.obj) >= 0
|
|
||||||
def __ne__(self, other):
|
|
||||||
return mycmp(self.obj, other.obj) != 0
|
|
||||||
return K
|
|
||||||
|
|
||||||
|
|
||||||
def pairwise(iterable):
|
def pairwise(iterable):
|
||||||
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||||
a, b = tee(iterable)
|
a, b = tee(iterable)
|
||||||
|
|
|
@ -2,7 +2,6 @@ django==1.8.2
|
||||||
django-celery-email==1.0.4
|
django-celery-email==1.0.4
|
||||||
django-fluent-dashboard==0.5
|
django-fluent-dashboard==0.5
|
||||||
https://github.com/glic3rinu/django-admin-tools/archive/master.zip
|
https://github.com/glic3rinu/django-admin-tools/archive/master.zip
|
||||||
IPy==0.81
|
|
||||||
django-extensions==1.5.2
|
django-extensions==1.5.2
|
||||||
django-transaction-signals==1.0.0
|
django-transaction-signals==1.0.0
|
||||||
django-celery==3.1.16
|
django-celery==3.1.16
|
||||||
|
|
|
@ -40,11 +40,11 @@ function main () {
|
||||||
# TODO setupceleryd shoudl change orchestra_start/stop/restart_services
|
# TODO setupceleryd shoudl change orchestra_start/stop/restart_services
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Do you want to use celery or cronbeat for task execution [cronbeat]? " task
|
read -p "Do you want to use celery or cronbeat (orchestra.contrib.tasks) for task execution [cronbeat]? " task
|
||||||
case $task in
|
case $task in
|
||||||
'celery' ) task=celery; break;;
|
'celery' ) task=celery; break;;
|
||||||
'cronbeat' ) task=cronbeat; break;;
|
'orchestra.contrib.tasks' ) task=orchestra.contrib.tasks; break;;
|
||||||
'' ) task=cronbeat; break;;
|
'' ) task=orchestra.contrib.tasks; break;;
|
||||||
* ) echo "Please answer celery or cronbeat.";;
|
* ) echo "Please answer celery or cronbeat.";;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in New Issue