diff --git a/TODO.md b/TODO.md
index 6d794be6..c3cbaaf5 100644
--- a/TODO.md
+++ b/TODO.md
@@ -170,10 +170,10 @@ django-admin.py compilemessages -l ca
https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#joining-strings-string-concat
-from django.utils.translation import ugettext
+from django.utils.translation import gettext
from django.utils import translation
translation.activate('ca')
-ugettext("Description")
+gettext("Description")
* saas validate_creation generic approach, for all backends. standard output
diff --git a/docs/create-services.md b/docs/create-services.md
index d0224237..b3abef44 100644
--- a/docs/create-services.md
+++ b/docs/create-services.md
@@ -59,7 +59,7 @@
```python
import os
import textwrap
- from django.utils.translation import ugettext_lazy as _
+ from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
from orchestra.contrib.resources import ServiceMonitor
diff --git a/orchestra/admin/__init__.py b/orchestra/admin/__init__.py
index 508aee46..393f4753 100644
--- a/orchestra/admin/__init__.py
+++ b/orchestra/admin/__init__.py
@@ -6,7 +6,7 @@ from django.contrib import admin
from django.urls import reverse
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .dashboard import *
from .options import *
diff --git a/orchestra/admin/actions.py b/orchestra/admin/actions.py
index e97d7e40..9bec0488 100644
--- a/orchestra/admin/actions.py
+++ b/orchestra/admin/actions.py
@@ -3,7 +3,7 @@ from functools import partial
from django.contrib import admin
from django.core.mail import send_mass_mail
from django.shortcuts import render
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from .. import settings
@@ -81,7 +81,7 @@ class SendEmail(object):
if extra_to:
emails.append((subject, message, email_from, extra_to))
send_mass_mail(emails, fail_silently=False)
- msg = ungettext(
+ msg = ngettext(
_("Message has been sent to one %s.") % self.opts.verbose_name_plural,
_("Message has been sent to %i %s.") % (num, self.opts.verbose_name_plural),
num
@@ -124,7 +124,7 @@ def base_disable(modeladmin, request, queryset, disable=True):
'verbose_name_plural': opts.verbose_name_plural,
'num': num
}
- msg = ungettext(
+ msg = ngettext(
_("Selected %(verbose_name)s and related services has been %(action_name)s.") % context,
_("%(num)s selected %(verbose_name_plural)s and related services have been %(action_name)s.") % context,
num)
diff --git a/orchestra/admin/dashboard.py b/orchestra/admin/dashboard.py
index 9237470d..7e73628d 100644
--- a/orchestra/admin/dashboard.py
+++ b/orchestra/admin/dashboard.py
@@ -1,5 +1,5 @@
from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from fluent_dashboard import dashboard, appsettings
from fluent_dashboard.modules import CmsAppIconList
diff --git a/orchestra/admin/decorators.py b/orchestra/admin/decorators.py
index 55afdc20..87f03757 100644
--- a/orchestra/admin/decorators.py
+++ b/orchestra/admin/decorators.py
@@ -4,11 +4,10 @@ from django.contrib import messages
from django.contrib.admin import helpers
from django.core.exceptions import ValidationError
from django.template.response import TemplateResponse
-from django.utils.decorators import available_attrs
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.html import format_html
from django.utils.text import capfirst
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
def admin_field(method):
@@ -50,7 +49,7 @@ def action_with_confirmation(action_name=None, extra_context=None, validator=Non
"""
def decorator(func, extra_context=extra_context, template=template, action_name=action_name, validatior=validator):
- @wraps(func, assigned=available_attrs(func))
+ @wraps(func)
def inner(modeladmin, request, queryset, action_name=action_name, extra_context=extra_context, validator=validator):
if validator is not None:
try:
@@ -69,10 +68,10 @@ def action_with_confirmation(action_name=None, extra_context=None, validator=Non
action_value = func.__name__
if len(queryset) == 1:
- objects_name = force_text(opts.verbose_name)
+ objects_name = force_str(opts.verbose_name)
obj = queryset.get()
else:
- objects_name = force_text(opts.verbose_name_plural)
+ objects_name = force_str(opts.verbose_name_plural)
obj = None
if not action_name:
action_name = func.__name__
diff --git a/orchestra/admin/forms.py b/orchestra/admin/forms.py
index 2490873f..f74df5e2 100644
--- a/orchestra/admin/forms.py
+++ b/orchestra/admin/forms.py
@@ -5,8 +5,8 @@ from django import forms
from django.contrib.admin import helpers
from django.core import validators
from django.forms.models import modelformset_factory, BaseModelFormSet
-from django.template import Template
-from django.utils.translation import ugettext_lazy as _
+from django.template import Template, Context
+from django.utils.translation import gettext_lazy as _
from orchestra.forms.widgets import SpanWidget
@@ -31,7 +31,7 @@ class AdminFormMixin(object):
context = {
'adminform': adminform
}
- return template.render(context)
+ return template.render(Context(context))
class AdminFormSet(BaseModelFormSet):
@@ -74,7 +74,7 @@ class AdminFormSet(BaseModelFormSet):
context = {
'formset': self
}
- return template.render(context)
+ return template.render(Context(context))
class AdminPasswordChangeForm(forms.Form):
diff --git a/orchestra/admin/menu.py b/orchestra/admin/menu.py
index 1c16f761..f849829e 100644
--- a/orchestra/admin/menu.py
+++ b/orchestra/admin/menu.py
@@ -3,7 +3,7 @@ from copy import deepcopy
from admin_tools.menu import items, Menu
from django.urls import reverse
from django.utils.text import capfirst
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import services, accounts, administration
@@ -73,7 +73,7 @@ class OrchestraMenu(Menu):
self.children = [
# items.MenuItem(
# mark_safe('{site_name} v{version}'.format(
-# site_name=force_text(settings.SITE_VERBOSE_NAME),
+# site_name=force_str(settings.SITE_VERBOSE_NAME),
# version_style="text-transform:none; float:none; font-size:smaller; background:none;",
# version=get_version())),
# reverse('admin:index')
diff --git a/orchestra/admin/options.py b/orchestra/admin/options.py
index f8b20367..3849bc20 100644
--- a/orchestra/admin/options.py
+++ b/orchestra/admin/options.py
@@ -1,7 +1,7 @@
from urllib import parse
from django import forms
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin, messages
from django.contrib.admin.options import IS_POPUP_VAR
from django.contrib.admin.utils import unquote
@@ -12,9 +12,9 @@ from django.forms.models import BaseInlineFormSet
from django.shortcuts import get_object_or_404
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.html import escape
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from django.views.decorators.debug import sensitive_post_parameters
from orchestra.models.utils import has_db_field
@@ -230,7 +230,7 @@ class ExtendedModelAdmin(ChangeViewActionsMixin,
if obj is None:
opts = self.model._meta
raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {
- 'name': force_text(opts.verbose_name), 'key': escape(object_id)})
+ 'name': force_str(opts.verbose_name), 'key': escape(object_id)})
return obj
diff --git a/orchestra/api/options.py b/orchestra/api/options.py
index 4d429a03..9e2a913e 100644
--- a/orchestra/api/options.py
+++ b/orchestra/api/options.py
@@ -1,8 +1,8 @@
from django.contrib.admin.options import get_content_type_for_model
from django.conf import settings as django_settings
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.module_loading import autodiscover_modules
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
from rest_framework.routers import DefaultRouter
from orchestra import settings
@@ -52,7 +52,7 @@ class LogApiMixin(object):
user_id=request.user.pk,
content_type_id=get_content_type_for_model(instance).pk,
object_id=instance.pk,
- object_repr=force_text(instance),
+ object_repr=force_str(instance),
action_flag=action,
change_message=message,
)
diff --git a/orchestra/api/serializers.py b/orchestra/api/serializers.py
index 01005771..4b6f4667 100644
--- a/orchestra/api/serializers.py
+++ b/orchestra/api/serializers.py
@@ -3,7 +3,7 @@ import copy
from django.core.exceptions import ValidationError
from django.db import models
from django.forms import widgets
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from rest_framework.utils import model_meta
diff --git a/orchestra/contrib/accounts/actions.py b/orchestra/contrib/accounts/actions.py
index b4bcff22..0bf45a00 100644
--- a/orchestra/contrib/accounts/actions.py
+++ b/orchestra/contrib/accounts/actions.py
@@ -9,10 +9,10 @@ from django.db import router
from django.shortcuts import redirect, render
from django.template.response import TemplateResponse
from django.utils import timezone
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.html import format_html
from django.utils.text import capfirst
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.core import services
@@ -84,7 +84,7 @@ def delete_related_services(modeladmin, request, queryset):
def format(obj, account=False):
has_admin = obj.__class__ in admin_site._registry
opts = obj._meta
- no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), force_text(obj))
+ no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), force_str(obj))
if has_admin:
try:
@@ -154,7 +154,7 @@ def delete_related_services(modeladmin, request, queryset):
if accounts:
relateds = len(to_delete)
for obj in to_delete:
- obj_display = force_text(obj)
+ obj_display = force_str(obj)
modeladmin.log_deletion(request, obj, obj_display)
obj.delete()
context = {
@@ -167,9 +167,9 @@ def delete_related_services(modeladmin, request, queryset):
return None
if len(queryset) == 1:
- objects_name = force_text(opts.verbose_name)
+ objects_name = force_str(opts.verbose_name)
else:
- objects_name = force_text(opts.verbose_name_plural)
+ objects_name = force_str(opts.verbose_name_plural)
model_count = {}
for model, objs in collector.model_objs.items():
@@ -214,7 +214,7 @@ def disable_selected(modeladmin, request, queryset, disable=True):
account.disable() if disable else account.enable()
modeladmin.log_change(request, account, verbose_action_name.capitalize())
n += 1
- modeladmin.message_user(request, ungettext(
+ modeladmin.message_user(request, ngettext(
_("One account has been successfully %s.") % verbose_action_name,
_("%i accounts have been successfully %s.") % (n, verbose_action_name),
n)
@@ -227,7 +227,7 @@ def disable_selected(modeladmin, request, queryset, disable=True):
def format(obj):
has_admin = obj.__class__ in admin_site._registry
opts = obj._meta
- no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), force_text(obj))
+ no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), force_str(obj))
if has_admin:
try:
admin_url = reverse(
@@ -258,9 +258,9 @@ def disable_selected(modeladmin, request, queryset, disable=True):
display.append([format(account), current])
if len(queryset) == 1:
- objects_name = force_text(opts.verbose_name)
+ objects_name = force_str(opts.verbose_name)
else:
- objects_name = force_text(opts.verbose_name_plural)
+ objects_name = force_str(opts.verbose_name_plural)
context = dict(
admin_site.each_context(request),
diff --git a/orchestra/contrib/accounts/admin.py b/orchestra/contrib/accounts/admin.py
index e44c656b..b2d6442a 100644
--- a/orchestra/contrib/accounts/admin.py
+++ b/orchestra/contrib/accounts/admin.py
@@ -4,7 +4,7 @@ from urllib.parse import parse_qsl
from django import forms
from django.apps import apps
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin, messages
from django.contrib.admin.utils import unquote
from django.contrib.auth import admin as auth
@@ -12,7 +12,7 @@ from django.urls import reverse
from django.http import HttpResponseRedirect
from django.templatetags.static import static
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import SendEmail
diff --git a/orchestra/contrib/accounts/api.py b/orchestra/contrib/accounts/api.py
index bef27d27..e602f908 100644
--- a/orchestra/contrib/accounts/api.py
+++ b/orchestra/contrib/accounts/api.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import viewsets, exceptions
from orchestra.api import router, SetPasswordApiMixin, LogApiMixin
diff --git a/orchestra/contrib/accounts/apps.py b/orchestra/contrib/accounts/apps.py
index 81e73667..4501614c 100644
--- a/orchestra/contrib/accounts/apps.py
+++ b/orchestra/contrib/accounts/apps.py
@@ -1,6 +1,6 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import services, accounts
diff --git a/orchestra/contrib/accounts/filters.py b/orchestra/contrib/accounts/filters.py
index d45ff8ff..ff4be0ae 100644
--- a/orchestra/contrib/accounts/filters.py
+++ b/orchestra/contrib/accounts/filters.py
@@ -1,6 +1,6 @@
from django.contrib.admin import SimpleListFilter
from django.db.models import Q
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class IsActiveListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/accounts/forms.py b/orchestra/contrib/accounts/forms.py
index a420c266..43689967 100644
--- a/orchestra/contrib/accounts/forms.py
+++ b/orchestra/contrib/accounts/forms.py
@@ -4,7 +4,7 @@ from collections import OrderedDict
from django import forms
from django.core.exceptions import ValidationError
from django.apps import apps
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.forms import UserCreationForm
diff --git a/orchestra/contrib/accounts/models.py b/orchestra/contrib/accounts/models.py
index 94cd29c6..b8c6a39a 100644
--- a/orchestra/contrib/accounts/models.py
+++ b/orchestra/contrib/accounts/models.py
@@ -5,7 +5,7 @@ from django.db import models
from django.db.models import signals
from django.apps import apps
from django.utils import timezone, translation
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
#from orchestra.contrib.orchestration.middlewares import OperationsMiddleware
#from orchestra.contrib.orchestration import Operation
@@ -165,7 +165,6 @@ class Account(auth.AbstractBaseUser):
elif obj and getattr(obj, 'account', None) == self:
return True
-
def has_perms(self, perm_list, obj=None):
"""
Returns True if the user has each of the specified permissions. If
diff --git a/orchestra/contrib/accounts/settings.py b/orchestra/contrib/accounts/settings.py
index 9ec510e7..b8a25944 100644
--- a/orchestra/contrib/accounts/settings.py
+++ b/orchestra/contrib/accounts/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
from orchestra.settings import ORCHESTRA_BASE_DOMAIN
diff --git a/orchestra/contrib/accounts/templates/admin/accounts/account/change_form.html b/orchestra/contrib/accounts/templates/admin/accounts/account/change_form.html
index d4404031..b1a41386 100644
--- a/orchestra/contrib/accounts/templates/admin/accounts/account/change_form.html
+++ b/orchestra/contrib/accounts/templates/admin/accounts/account/change_form.html
@@ -1,5 +1,5 @@
{% extends "orchestra/admin/change_form.html" %}
-{% load i18n admin_urls admin_static admin_modify %}
+{% load i18n admin_urls static admin_modify %}
{% block breadcrumbs %}
diff --git a/orchestra/contrib/bills/actions.py b/orchestra/contrib/bills/actions.py
index 37723b42..64c9ed57 100644
--- a/orchestra/contrib/bills/actions.py
+++ b/orchestra/contrib/bills/actions.py
@@ -12,7 +12,7 @@ from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from django.utils import translation, timezone
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.admin.decorators import action_with_confirmation
from orchestra.admin.forms import AdminFormSet
@@ -69,7 +69,7 @@ def close_bills(modeladmin, request, queryset, action='close_bills'):
'url': url,
'num': num,
}
- message = ungettext(
+ message = ngettext(
_('One related transaction has been created') % context,
_('%(num)i related transactions have been created') % context,
num)
@@ -111,7 +111,7 @@ def send_bills_action(modeladmin, request, queryset):
bill.send()
modeladmin.log_change(request, bill, 'Sent')
num += 1
- messages.success(request, ungettext(
+ messages.success(request, ngettext(
_("One bill has been sent."),
_("%i bills have been sent.") % num,
num))
@@ -135,7 +135,7 @@ def download_bills(modeladmin, request, queryset):
pdf = bill.as_pdf()
archive.writestr('%s.pdf' % bill.number, pdf)
archive.close()
- response = HttpResponse(bytesio.getvalue(), content_type='application/pdf')
+ response = HttpResponse(bytesio.getvalue(), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="orchestra-bills.zip"'
return response
bill = queryset[0]
@@ -299,7 +299,7 @@ def amend_bills(modeladmin, request, queryset):
'url': amend_url,
'num': num,
}
- messages.success(request, mark_safe(ungettext(
+ messages.success(request, mark_safe(ngettext(
_('One amendment bill have been generated.') % context,
_('%(num)i amendment bills have been generated.') % context,
num
diff --git a/orchestra/contrib/bills/admin.py b/orchestra/contrib/bills/admin.py
index 8d23ca04..ac453dbe 100644
--- a/orchestra/contrib/bills/admin.py
+++ b/orchestra/contrib/bills/admin.py
@@ -1,5 +1,5 @@
from django import forms
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin, messages
from django.contrib.admin.utils import unquote
from django.urls import reverse
@@ -9,7 +9,7 @@ from django.db.models.functions import Coalesce
from django.templatetags.static import static
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from django.shortcuts import redirect
from orchestra.admin import ExtendedModelAdmin
@@ -126,7 +126,7 @@ class ClosedBillLineInline(BillLineInline):
return line.compute_total()
display_total.short_description = _("Total")
- def has_add_permission(self, request):
+ def has_add_permission(self, request, obj):
return False
diff --git a/orchestra/contrib/bills/filters.py b/orchestra/contrib/bills/filters.py
index a4beb32f..adcf5753 100644
--- a/orchestra/contrib/bills/filters.py
+++ b/orchestra/contrib/bills/filters.py
@@ -2,7 +2,7 @@ from django.contrib.admin import SimpleListFilter
from django.urls import reverse
from django.db.models import Q
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from . models import Bill
diff --git a/orchestra/contrib/bills/forms.py b/orchestra/contrib/bills/forms.py
index 7105e63f..b4759928 100644
--- a/orchestra/contrib/bills/forms.py
+++ b/orchestra/contrib/bills/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import admin_link
from orchestra.forms import SpanWidget
diff --git a/orchestra/contrib/bills/helpers.py b/orchestra/contrib/bills/helpers.py
index 23c72fcc..d255e931 100644
--- a/orchestra/contrib/bills/helpers.py
+++ b/orchestra/contrib/bills/helpers.py
@@ -1,10 +1,10 @@
from django.contrib import messages
from django.urls import reverse
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.text import capfirst
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import change_url
@@ -16,14 +16,14 @@ def validate_contact(request, bill, error=True):
valid = True
send = messages.error if error else messages.warning
if not hasattr(bill.account, 'billcontact'):
- account = force_text(bill.account)
+ account = force_str(bill.account)
url = reverse('admin:accounts_account_change', args=(bill.account_id,))
message = msg.format(relation=_("Related"), account=account, url=url)
send(request, mark_safe(message))
valid = False
main = type(bill).account.field.related_model.objects.get_main()
if not hasattr(main, 'billcontact'):
- account = force_text(main)
+ account = force_str(main)
url = reverse('admin:accounts_account_change', args=(main.id,))
message = msg.format(relation=_("Main"), account=account, url=url)
send(request, mark_safe(message))
diff --git a/orchestra/contrib/bills/models.py b/orchestra/contrib/bills/models.py
index 90765ca3..9510f6b6 100644
--- a/orchestra/contrib/bills/models.py
+++ b/orchestra/contrib/bills/models.py
@@ -8,9 +8,9 @@ from django.db.models import F, Sum
from django.db.models.functions import Coalesce
from django.template import loader
from django.utils import timezone, translation
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import change_url
from orchestra.contrib.accounts.models import Account
@@ -209,7 +209,7 @@ class Bill(models.Model):
def get_payment_state_display(self):
value = self.payment_state
- return force_text(dict(self.PAYMENT_STATES).get(value, value))
+ return force_str(dict(self.PAYMENT_STATES).get(value, value))
def get_current_transaction(self):
return self.transactions.exclude_rejected().first()
diff --git a/orchestra/contrib/contacts/admin.py b/orchestra/contrib/contacts/admin.py
index 82adc381..c5c76471 100644
--- a/orchestra/contrib/contacts/admin.py
+++ b/orchestra/contrib/contacts/admin.py
@@ -1,6 +1,6 @@
from django import forms
from django.contrib import admin
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import AtLeastOneRequiredInlineFormSet, ExtendedModelAdmin
from orchestra.admin.actions import SendEmail
diff --git a/orchestra/contrib/contacts/filters.py b/orchestra/contrib/contacts/filters.py
index 2ffae3ed..0f36a547 100644
--- a/orchestra/contrib/contacts/filters.py
+++ b/orchestra/contrib/contacts/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .models import Contact
diff --git a/orchestra/contrib/contacts/models.py b/orchestra/contrib/contacts/models.py
index a8de1580..2f069afb 100644
--- a/orchestra/contrib/contacts/models.py
+++ b/orchestra/contrib/contacts/models.py
@@ -1,7 +1,7 @@
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import validators
from orchestra.models.fields import MultiSelectField
diff --git a/orchestra/contrib/databases/admin.py b/orchestra/contrib/databases/admin.py
index d50c23d4..21ca6da9 100644
--- a/orchestra/contrib/databases/admin.py
+++ b/orchestra/contrib/databases/admin.py
@@ -1,9 +1,9 @@
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.utils import change_url
@@ -11,7 +11,7 @@ from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
from .filters import HasUserListFilter, HasDatabaseListFilter
-from .forms import DatabaseCreationForm, DatabaseUserChangeForm, DatabaseUserCreationForm
+from .forms import DatabaseCreationForm, DatabaseUserChangeForm, DatabaseUserCreationForm, DatabaseForm
from .models import Database, DatabaseUser
def save_selected(modeladmin, request, queryset):
@@ -23,18 +23,18 @@ class DatabaseAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
list_display = ('name', 'type', 'display_users', 'account_link')
list_filter = ('type', HasUserListFilter)
search_fields = ('name', 'account__username')
- change_readonly_fields = ('name', 'type')
+ change_readonly_fields = ('name', 'type', 'target_server')
extra = 1
fieldsets = (
(None, {
'classes': ('extrapretty',),
- 'fields': ('account_link', 'name', 'type', 'users', 'display_users', 'comments'),
+ 'fields': ('account_link', 'name', 'type', 'users', 'display_users', 'comments', 'target_server'),
}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
- 'fields': ('account_link', 'name', 'type')
+ 'fields': ('account_link', 'name', 'type', 'target_server')
}),
(_("Create new user"), {
'classes': ('wide',),
@@ -45,11 +45,12 @@ class DatabaseAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
'fields': ('user',)
}),
)
+ form = DatabaseForm
add_form = DatabaseCreationForm
readonly_fields = ('account_link', 'display_users',)
filter_horizontal = ['users']
- filter_by_account_fields = ('users',)
- list_prefetch_related = ('users',)
+ # filter_by_account_fields = ('users',)
+ # list_prefetch_related = ('users',)
actions = (list_accounts, save_selected)
@mark_safe
@@ -71,6 +72,7 @@ class DatabaseAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
username=form.cleaned_data['username'],
type=obj.type,
account_id=obj.account.pk,
+ target_server=form.cleaned_data['target_server'],
)
user.set_password(form.cleaned_data["password1"])
user.save()
@@ -78,22 +80,22 @@ class DatabaseAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
class DatabaseUserAdmin(SelectAccountAdminMixin, ChangePasswordAdminMixin, ExtendedModelAdmin):
- list_display = ('username', 'type', 'display_databases', 'account_link')
+ list_display = ('username', 'target_server', 'type', 'display_databases', 'account_link')
list_filter = ('type', HasDatabaseListFilter)
search_fields = ('username', 'account__username')
form = DatabaseUserChangeForm
add_form = DatabaseUserCreationForm
- change_readonly_fields = ('username', 'type')
+ change_readonly_fields = ('username', 'type', 'target_server')
fieldsets = (
(None, {
'classes': ('extrapretty',),
- 'fields': ('account_link', 'username', 'password', 'type', 'display_databases')
+ 'fields': ('account_link', 'username', 'password', 'type', 'display_databases', 'target_server', 'permision')
}),
)
add_fieldsets = (
(None, {
'classes': ('extrapretty',),
- 'fields': ('account_link', 'username', 'password1', 'password2', 'type')
+ 'fields': ('account_link', 'username', 'password1', 'password2', 'type', 'target_server', 'permision')
}),
)
readonly_fields = ('account_link', 'display_databases',)
diff --git a/orchestra/contrib/databases/apps.py b/orchestra/contrib/databases/apps.py
index 97f8ef4a..87e89386 100644
--- a/orchestra/contrib/databases/apps.py
+++ b/orchestra/contrib/databases/apps.py
@@ -1,5 +1,5 @@
from django.apps import AppConfig
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import services
diff --git a/orchestra/contrib/databases/backends.py b/orchestra/contrib/databases/backends.py
index 29e764ba..ca48ff03 100644
--- a/orchestra/contrib/databases/backends.py
+++ b/orchestra/contrib/databases/backends.py
@@ -1,6 +1,6 @@
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
from orchestra.contrib.resources import ServiceMonitor
@@ -36,10 +36,16 @@ class MySQLController(ServiceController):
'username': user.username,
'grant': 'WITH GRANT OPTION' if user == context['owner'] else ''
})
- self.append(textwrap.dedent("""\
- mysql -e 'GRANT ALL PRIVILEGES ON `%(database)s`.* TO "%(username)s"@"%(host)s" %(grant)s;'\
- """) % context
- )
+ if user.permision == "ro":
+ self.append(textwrap.dedent("""\
+ mysql -e 'GRANT SELECT ON `%(database)s`.* TO "%(username)s"@"%(host)s" %(grant)s;'\
+ """) % context
+ )
+ else:
+ self.append(textwrap.dedent("""\
+ mysql -e 'GRANT ALL PRIVILEGES ON `%(database)s`.* TO "%(username)s"@"%(host)s" %(grant)s;'\
+ """) % context
+ )
def delete(self, database):
if database.type != database.MYSQL:
@@ -83,12 +89,20 @@ class MySQLUserController(ServiceController):
if user.type != user.MYSQL:
return
context = self.get_context(user)
- self.append(textwrap.dedent("""\
- # Create user %(username)s
- mysql -e 'CREATE USER "%(username)s"@"%(host)s";' || true # User already exists
- mysql -e 'UPDATE mysql.user SET Password="%(password)s" WHERE User="%(username)s";'\
- """) % context
- )
+ if user.target_server.name != "mysql.pangea.lan":
+ self.append(textwrap.dedent("""\
+ # Create user %(username)s
+ mysql -e 'CREATE USER IF NOT EXISTS "%(username)s"@"%(host)s";'
+ mysql -e 'ALTER USER IF EXISTS "%(username)s"@"%(host)s" IDENTIFIED BY PASSWORD "%(password)s";'\
+ """) % context
+ )
+ else:
+ self.append(textwrap.dedent("""\
+ # Create user %(username)s
+ mysql -e 'CREATE USER "%(username)s"@"%(host)s";' || true # User already exists
+ mysql -e 'UPDATE mysql.user SET Password="%(password)s" WHERE User="%(username)s";'\
+ """) % context
+ )
def delete(self, user):
if user.type != user.MYSQL:
@@ -172,7 +186,7 @@ class MysqlDisk(ServiceMonitor):
def get_context(self, db):
context = {
'db_name': db.name,
- 'db_dirname': db.name.replace('-', '@003f'),
+ 'db_dirname': db.name.replace('-', '@002d'),
'db_id': db.pk,
'db_type': db.type,
}
diff --git a/orchestra/contrib/databases/filters.py b/orchestra/contrib/databases/filters.py
index 9b76957a..50136c70 100644
--- a/orchestra/contrib/databases/filters.py
+++ b/orchestra/contrib/databases/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class HasUserListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/databases/forms.py b/orchestra/contrib/databases/forms.py
index aa4c720a..f35f00c7 100644
--- a/orchestra/contrib/databases/forms.py
+++ b/orchestra/contrib/databases/forms.py
@@ -3,7 +3,7 @@ from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import validators
@@ -31,6 +31,32 @@ class DatabaseUserCreationForm(forms.ModelForm):
return password2
+class DatabaseForm(forms.ModelForm):
+
+ class Meta:
+ model = Database
+ fields = ('name', 'users', 'type', 'account', 'target_server')
+
+ def __init__(self, *args, **kwargs):
+ super(DatabaseForm, self).__init__(*args, **kwargs)
+ # muestra solo los usuarios del mismo server
+ account_id = self.instance.account_id
+ database_server_id = self.instance.target_server_id
+ if account_id:
+ self.fields['users'].queryset = DatabaseUser.objects.filter(account=account_id, target_server=database_server_id)
+
+ def clean(self):
+ # verifica que los usuarios petenecen al servidor de la bbdd
+ database_server_id = self.instance.target_server_id
+ users = self.cleaned_data.get('users')
+ if users and database_server_id:
+ for user in users:
+ if user.target_server_id != database_server_id:
+ self.add_error("users", _(f"{user.username} does not belong to the database server"))
+
+ return self.cleaned_data
+
+
class DatabaseCreationForm(DatabaseUserCreationForm):
username = forms.CharField(label=_("Username"), max_length=16,
required=False, validators=[validators.validate_name],
@@ -50,13 +76,14 @@ class DatabaseCreationForm(DatabaseUserCreationForm):
account_id = self.initial.get('account', self.initial_account)
if account_id:
qs = self.fields['user'].queryset.filter(account=account_id).order_by('username')
- choices = [ (u.pk, "%s (%s)" % (u, u.get_type_display())) for u in qs ]
+ choices = [ (u.pk, "%s (%s) (%s)" % (u, u.get_type_display(), str(u.target_server.name) )) for u in qs ]
self.fields['user'].queryset = qs
self.fields['user'].choices = [(None, '--------'),] + choices
def clean_username(self):
username = self.cleaned_data.get('username')
- if DatabaseUser.objects.filter(username=username).exists():
+ server = self.cleaned_data.get('target_server')
+ if DatabaseUser.objects.filter(username=username, target_server=server).exists():
raise ValidationError("Provided username already exists.")
return username
@@ -76,6 +103,9 @@ class DatabaseCreationForm(DatabaseUserCreationForm):
if user and user.type != self.cleaned_data.get('type'):
msg = _("Database type and user type doesn't match")
raise ValidationError(msg)
+ if user and user.target_server != self.cleaned_data.get('target_server'):
+ msg = _("Database server and user server doesn't match")
+ raise ValidationError(msg)
return user
def clean(self):
diff --git a/orchestra/contrib/databases/migrations/0001_initial.py b/orchestra/contrib/databases/migrations/0001_initial.py
index e25696ac..cf3f8f85 100644
--- a/orchestra/contrib/databases/migrations/0001_initial.py
+++ b/orchestra/contrib/databases/migrations/0001_initial.py
@@ -1,52 +1,46 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
+# Generated by Django 2.2.28 on 2023-06-28 17:06
-from django.db import models, migrations
from django.conf import settings
+from django.db import migrations, models
import django.db.models.deletion
import orchestra.core.validators
class Migration(migrations.Migration):
+ initial = True
+
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
- migrations.CreateModel(
- name='Database',
- fields=[
- ('id', models.AutoField(serialize=False, primary_key=True, verbose_name='ID', auto_created=True)),
- ('name', models.CharField(verbose_name='name', max_length=64, validators=[orchestra.core.validators.validate_name])),
- ('type', models.CharField(default='mysql', choices=[('mysql', 'MySQL'), ('postgres', 'PostgreSQL')], verbose_name='type', max_length=32)),
- ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='databases', verbose_name='Account', to=settings.AUTH_USER_MODEL)),
- ],
- ),
migrations.CreateModel(
name='DatabaseUser',
fields=[
- ('id', models.AutoField(serialize=False, primary_key=True, verbose_name='ID', auto_created=True)),
- ('username', models.CharField(verbose_name='username', max_length=16, validators=[orchestra.core.validators.validate_name])),
- ('password', models.CharField(verbose_name='password', max_length=256)),
- ('type', models.CharField(default='mysql', choices=[('mysql', 'MySQL'), ('postgres', 'PostgreSQL')], verbose_name='type', max_length=32)),
- ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='databaseusers', verbose_name='Account', to=settings.AUTH_USER_MODEL)),
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('username', models.CharField(max_length=16, validators=[orchestra.core.validators.validate_name], verbose_name='username')),
+ ('password', models.CharField(max_length=256, verbose_name='password')),
+ ('type', models.CharField(choices=[('mysql', 'MySQL')], default='mysql', max_length=32, verbose_name='type')),
+ ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='databaseusers', to=settings.AUTH_USER_MODEL, verbose_name='Account')),
],
options={
'verbose_name_plural': 'DB users',
+ 'unique_together': {('username', 'type')},
},
),
- migrations.AddField(
- model_name='database',
- name='users',
- field=models.ManyToManyField(related_name='databases', to='databases.DatabaseUser', verbose_name='users', blank=True),
- ),
- migrations.AlterUniqueTogether(
- name='databaseuser',
- unique_together=set([('username', 'type')]),
- ),
- migrations.AlterUniqueTogether(
- name='database',
- unique_together=set([('name', 'type')]),
+ migrations.CreateModel(
+ name='Database',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=64, validators=[orchestra.core.validators.validate_name], verbose_name='name')),
+ ('type', models.CharField(choices=[('mysql', 'MySQL')], default='mysql', max_length=32, verbose_name='type')),
+ ('comments', models.TextField(blank=True, default='')),
+ ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='databases', to=settings.AUTH_USER_MODEL, verbose_name='Account')),
+ ('users', models.ManyToManyField(blank=True, related_name='databases', to='databases.DatabaseUser', verbose_name='users')),
+ ],
+ options={
+ 'unique_together': {('name', 'type')},
+ },
),
]
diff --git a/orchestra/contrib/databases/migrations/0002_databaseuser_target_server.py b/orchestra/contrib/databases/migrations/0002_databaseuser_target_server.py
new file mode 100644
index 00000000..3db3d0ca
--- /dev/null
+++ b/orchestra/contrib/databases/migrations/0002_databaseuser_target_server.py
@@ -0,0 +1,20 @@
+# Generated by Django 2.2.28 on 2023-06-28 17:11
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orchestration', '__first__'),
+ ('databases', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='databaseuser',
+ name='target_server',
+ field=models.ForeignKey(default=3, on_delete=django.db.models.deletion.CASCADE, to='orchestration.Server', verbose_name='Target Server'),
+ ),
+ ]
diff --git a/orchestra/contrib/databases/migrations/0003_auto_20230629_1838.py b/orchestra/contrib/databases/migrations/0003_auto_20230629_1838.py
new file mode 100644
index 00000000..cd71691f
--- /dev/null
+++ b/orchestra/contrib/databases/migrations/0003_auto_20230629_1838.py
@@ -0,0 +1,29 @@
+# Generated by Django 2.2.28 on 2023-06-29 16:38
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orchestration', '__first__'),
+ ('databases', '0002_databaseuser_target_server'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='databaseuser',
+ name='permision',
+ field=models.CharField(choices=[('all', 'all'), ('ro', 'read only')], default='all', max_length=20, verbose_name='Permisson'),
+ ),
+ migrations.AlterField(
+ model_name='databaseuser',
+ name='target_server',
+ field=models.ForeignKey(default=3, on_delete=django.db.models.deletion.CASCADE, to='orchestration.Server', verbose_name='Server'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='databaseuser',
+ unique_together={('username', 'type', 'target_server')},
+ ),
+ ]
diff --git a/orchestra/contrib/databases/migrations/0004_database_target_server.py b/orchestra/contrib/databases/migrations/0004_database_target_server.py
new file mode 100644
index 00000000..2868cbfb
--- /dev/null
+++ b/orchestra/contrib/databases/migrations/0004_database_target_server.py
@@ -0,0 +1,20 @@
+# Generated by Django 2.2.28 on 2023-06-29 16:57
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orchestration', '__first__'),
+ ('databases', '0003_auto_20230629_1838'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='database',
+ name='target_server',
+ field=models.ForeignKey(default=3, on_delete=django.db.models.deletion.CASCADE, to='orchestration.Server', verbose_name='Server'),
+ ),
+ ]
diff --git a/orchestra/contrib/databases/migrations/0005_auto_20230705_1208.py b/orchestra/contrib/databases/migrations/0005_auto_20230705_1208.py
new file mode 100644
index 00000000..55285684
--- /dev/null
+++ b/orchestra/contrib/databases/migrations/0005_auto_20230705_1208.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.28 on 2023-07-05 10:08
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orchestration', '__first__'),
+ ('databases', '0004_database_target_server'),
+ ]
+
+ operations = [
+ migrations.AlterUniqueTogether(
+ name='database',
+ unique_together={('name', 'type', 'target_server')},
+ ),
+ ]
diff --git a/orchestra/contrib/databases/migrations/0006_auto_20230705_1237.py b/orchestra/contrib/databases/migrations/0006_auto_20230705_1237.py
new file mode 100644
index 00000000..a0864891
--- /dev/null
+++ b/orchestra/contrib/databases/migrations/0006_auto_20230705_1237.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.2.28 on 2023-07-05 10:37
+
+from django.db import migrations, models
+import orchestra.core.validators
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('databases', '0005_auto_20230705_1208'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='databaseuser',
+ name='username',
+ field=models.CharField(max_length=32, validators=[orchestra.core.validators.validate_name], verbose_name='username'),
+ ),
+ ]
diff --git a/orchestra/contrib/databases/models.py b/orchestra/contrib/databases/models.py
index 207fe63d..528657f6 100644
--- a/orchestra/contrib/databases/models.py
+++ b/orchestra/contrib/databases/models.py
@@ -1,7 +1,7 @@
import hashlib
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import validators
@@ -23,9 +23,11 @@ class Database(models.Model):
account = models.ForeignKey('accounts.Account', on_delete=models.CASCADE,
verbose_name=_("Account"), related_name='databases')
comments = models.TextField(default="", blank=True)
+ target_server = models.ForeignKey('orchestration.Server', on_delete=models.CASCADE,
+ verbose_name=_("Server"), default=3 )
class Meta:
- unique_together = ('name', 'type')
+ unique_together = ('name', 'type', 'target_server')
def __str__(self):
return "%s" % self.name
@@ -54,7 +56,12 @@ class DatabaseUser(models.Model):
MYSQL = Database.MYSQL
POSTGRESQL = Database.POSTGRESQL
- username = models.CharField(_("username"), max_length=16, # MySQL usernames 16 char long
+ typeOfPermision = [
+ ('all','all'),
+ ('ro', 'read only'),
+ ]
+
+ username = models.CharField(_("username"), max_length=32, # MySQL usernames 16 char long
validators=[validators.validate_name])
password = models.CharField(_("password"), max_length=256)
type = models.CharField(_("type"), max_length=32,
@@ -62,10 +69,14 @@ class DatabaseUser(models.Model):
default=settings.DATABASES_DEFAULT_TYPE)
account = models.ForeignKey('accounts.Account', on_delete=models.CASCADE,
verbose_name=_("Account"), related_name='databaseusers')
+ target_server = models.ForeignKey('orchestration.Server', on_delete=models.CASCADE,
+ verbose_name=_("Server"), default=3 )
+ permision = models.CharField(verbose_name=_("Permisson"), max_length=20, choices=typeOfPermision, default='all')
+
class Meta:
verbose_name_plural = _("DB users")
- unique_together = ('username', 'type')
+ unique_together = ('username', 'type', 'target_server')
def __str__(self):
return self.username
diff --git a/orchestra/contrib/domains/actions.py b/orchestra/contrib/domains/actions.py
index 6b66188c..0e1b222f 100644
--- a/orchestra/contrib/domains/actions.py
+++ b/orchestra/contrib/domains/actions.py
@@ -7,7 +7,7 @@ from django.db.models.functions import Concat, Coalesce
from django.forms.models import modelformset_factory
from django.shortcuts import render
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from django.template.response import TemplateResponse
from orchestra.admin.utils import get_object_from_url, change_url, admin_link
@@ -84,7 +84,7 @@ def edit_records(modeladmin, request, queryset):
change_message = modeladmin.construct_change_message(request, fake_form, [formset])
modeladmin.log_change(request, formset.instance, change_message)
num = len(formsets)
- message = ungettext(
+ message = ngettext(
_("Records for one selected domain have been updated."),
_("Records for %i selected domains have been updated.") % num,
num)
@@ -127,7 +127,7 @@ def set_soa(modeladmin, request, queryset):
modeladmin.log_change(request, domain, change_message)
domain.save()
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("SOA record for one domain has been updated."),
_("SOA record for %s domains has been updated.") % num,
num
diff --git a/orchestra/contrib/domains/admin.py b/orchestra/contrib/domains/admin.py
index a1dd6141..10994cf4 100644
--- a/orchestra/contrib/domains/admin.py
+++ b/orchestra/contrib/domains/admin.py
@@ -5,7 +5,7 @@ from django.db.models.functions import Concat, Coalesce
from django.templatetags.static import static
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext, ugettext_lazy as _
+from django.utils.translation import gettext, gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.utils import admin_link, change_url
diff --git a/orchestra/contrib/domains/backends.py b/orchestra/contrib/domains/backends.py
index f372b6e2..e160e61b 100644
--- a/orchestra/contrib/domains/backends.py
+++ b/orchestra/contrib/domains/backends.py
@@ -2,7 +2,7 @@ import re
import socket
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.orchestration import Operation
diff --git a/orchestra/contrib/domains/filters.py b/orchestra/contrib/domains/filters.py
index 589079a4..c12f48e2 100644
--- a/orchestra/contrib/domains/filters.py
+++ b/orchestra/contrib/domains/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class TopDomainListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/domains/forms.py b/orchestra/contrib/domains/forms.py
index c73e92a7..15db21c8 100644
--- a/orchestra/contrib/domains/forms.py
+++ b/orchestra/contrib/domains/forms.py
@@ -1,7 +1,7 @@
from django import forms
from django.core.exceptions import ValidationError
from django.utils.text import capfirst
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.forms import AdminFormSet, AdminFormMixin
diff --git a/orchestra/contrib/domains/models.py b/orchestra/contrib/domains/models.py
index 05434559..9d099aa4 100644
--- a/orchestra/contrib/domains/models.py
+++ b/orchestra/contrib/domains/models.py
@@ -1,6 +1,6 @@
from django.core.exceptions import ValidationError
from django.db import models
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.core.validators import validate_ipv4_address, validate_ipv6_address, validate_ascii
from orchestra.utils.python import AttrDict
@@ -114,7 +114,7 @@ class Domain(models.Model):
def get_description(self):
if self.is_top:
num = self.subdomains.count()
- return ungettext(
+ return ngettext(
_("top domain with one subdomain"),
_("top domain with %d subdomains") % num,
num)
@@ -144,6 +144,10 @@ class Domain(models.Model):
tail.append(subdomain)
else:
zone += subdomain.render_records()
+ ###darmengo 2021-03-25 add autoconfig
+ if self.has_default_mx():
+ zone += 'autoconfig.{}. 30m IN A 109.69.8.133\n'.format(self.name)
+ ###END darmengo 2021-03-25 add autoconfig
for subdomain in sorted(tail, key=lambda x: len(x.name), reverse=True):
zone += subdomain.render_records()
return zone.strip()
diff --git a/orchestra/contrib/domains/serializers.py b/orchestra/contrib/domains/serializers.py
index 96451a56..7c6bebd6 100644
--- a/orchestra/contrib/domains/serializers.py
+++ b/orchestra/contrib/domains/serializers.py
@@ -1,5 +1,5 @@
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.api.serializers import HyperlinkedModelSerializer
diff --git a/orchestra/contrib/domains/templates/admin/domains/domain/change_form.html b/orchestra/contrib/domains/templates/admin/domains/domain/change_form.html
index c14c9254..5bf4ffb4 100644
--- a/orchestra/contrib/domains/templates/admin/domains/domain/change_form.html
+++ b/orchestra/contrib/domains/templates/admin/domains/domain/change_form.html
@@ -1,5 +1,5 @@
{% extends "admin/change_form.html" %}
-{% load i18n admin_urls admin_static admin_modify %}
+{% load i18n admin_urls static admin_modify %}
{% block object-tools-items %}
diff --git a/orchestra/contrib/domains/validators.py b/orchestra/contrib/domains/validators.py
index c3e1ed61..4722493a 100644
--- a/orchestra/contrib/domains/validators.py
+++ b/orchestra/contrib/domains/validators.py
@@ -3,7 +3,7 @@ import os
import re
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core.validators import validate_hostname
from orchestra.utils import paths
diff --git a/orchestra/contrib/history/admin.py b/orchestra/contrib/history/admin.py
index bc32e734..903eeda0 100644
--- a/orchestra/contrib/history/admin.py
+++ b/orchestra/contrib/history/admin.py
@@ -1,12 +1,12 @@
from django.contrib import admin
-from django.contrib.admin.templatetags.admin_static import static
+from django.templatetags.static import static
from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
from django.contrib.admin.utils import unquote
from django.http import HttpResponseRedirect
from django.urls import NoReverseMatch, reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import admin_date, admin_link
diff --git a/orchestra/contrib/issues/actions.py b/orchestra/contrib/issues/actions.py
index 3e6e1dde..dac29765 100644
--- a/orchestra/contrib/issues/actions.py
+++ b/orchestra/contrib/issues/actions.py
@@ -2,7 +2,7 @@ import sys
from django.contrib import messages
from django.db import transaction
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.admin.decorators import action_with_confirmation
@@ -102,7 +102,7 @@ def mark_as_unread(modeladmin, request, queryset):
ticket.mark_as_unread_by(request.user)
modeladmin.log_change(request, ticket, 'Marked as unread')
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("Selected ticket has been marked as unread."),
_("%i selected tickets have been marked as unread.") % num,
num)
@@ -116,7 +116,7 @@ def mark_as_read(modeladmin, request, queryset):
ticket.mark_as_read_by(request.user)
modeladmin.log_change(request, ticket, 'Marked as read')
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("Selected ticket has been marked as read."),
_("%i selected tickets have been marked as read.") % num,
num)
diff --git a/orchestra/contrib/issues/admin.py b/orchestra/contrib/issues/admin.py
index 7b607fe9..25ae3f21 100644
--- a/orchestra/contrib/issues/admin.py
+++ b/orchestra/contrib/issues/admin.py
@@ -1,5 +1,5 @@
from django import forms
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin
from django.urls import reverse
from django.db import models
@@ -7,7 +7,7 @@ from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils.html import format_html, strip_tags
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from markdown import markdown
from orchestra.admin import ExtendedModelAdmin
@@ -68,7 +68,7 @@ class MessageReadOnlyInline(admin.TabularInline):
return header + content
content_html.short_description = _("Content")
- def has_add_permission(self, request):
+ def has_add_permission(self, request, obj):
return False
def has_delete_permission(self, request, obj=None):
diff --git a/orchestra/contrib/issues/filters.py b/orchestra/contrib/issues/filters.py
index 142fd1d4..d0431feb 100644
--- a/orchestra/contrib/issues/filters.py
+++ b/orchestra/contrib/issues/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .models import Ticket
diff --git a/orchestra/contrib/issues/forms.py b/orchestra/contrib/issues/forms.py
index 292c85aa..137e7097 100644
--- a/orchestra/contrib/issues/forms.py
+++ b/orchestra/contrib/issues/forms.py
@@ -2,7 +2,7 @@ from django import forms
from django.contrib.auth import get_user_model
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from django.templatetags.static import static
from markdown import markdown
diff --git a/orchestra/contrib/issues/models.py b/orchestra/contrib/issues/models.py
index 8c783ea3..717f3acf 100644
--- a/orchestra/contrib/issues/models.py
+++ b/orchestra/contrib/issues/models.py
@@ -1,7 +1,7 @@
from django.conf import settings as djsettings
from django.db import models
from django.db.models import query, Q
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.contacts import settings as contacts_settings
from orchestra.contrib.contacts.models import Contact
diff --git a/orchestra/contrib/letsencrypt/actions.py b/orchestra/contrib/letsencrypt/actions.py
index b484494f..375933ac 100644
--- a/orchestra/contrib/letsencrypt/actions.py
+++ b/orchestra/contrib/letsencrypt/actions.py
@@ -1,7 +1,7 @@
from django.contrib import messages, admin
from django.template.response import TemplateResponse
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext, gettext_lazy as _
from orchestra.admin.utils import admin_link
from orchestra.contrib.orchestration import Operation, helpers
@@ -16,12 +16,12 @@ def letsencrypt(modeladmin, request, queryset):
content_error = ''
contentless = queryset.exclude(content__path='/').distinct()
if contentless:
- content_error = ungettext(
- ugettext("Selected website %s doesn't have a webapp mounted on /."),
- ugettext("Selected websites %s don't have a webapp mounted on /."),
+ content_error = ngettext(
+ gettext("Selected website %s doesn't have a webapp mounted on /."),
+ gettext("Selected websites %s don't have a webapp mounted on /."),
len(contentless),
)
- content_error += ugettext("
Websites need a webapp (e.g. static) mounted on / "
+ content_error += gettext("
Websites need a webapp (e.g. static) mounted on / "
"for let's encrypt HTTP-01 challenge to work.")
content_error = content_error % ', '.join((admin_link()(website) for website in contentless))
content_error = '
' % content_error
@@ -76,19 +76,19 @@ def letsencrypt(modeladmin, request, queryset):
'no_https': no_https
}
if errors:
- msg = ungettext(
+ msg = ngettext(
_("No lineages found for websites {name}."),
_("No lineages found for {errors} websites."),
errors)
messages.error(request, msg % context)
if successes:
- msg = ungettext(
+ msg = ngettext(
_("{name} website has successfully been encrypted."),
_("{successes} websites have been successfully encrypted."),
successes)
messages.success(request, msg.format(**context))
if no_https:
- msg = ungettext(
+ msg = ngettext(
_("{name} website does not have HTTPS protocol enabled."),
_("{no_https} websites do not have HTTPS protocol enabled."),
no_https)
@@ -99,7 +99,7 @@ def letsencrypt(modeladmin, request, queryset):
context = {
'title': _("Let's encrypt!"),
'action_name': _("Encrypt"),
- 'content_message': ugettext("You are going to request certificates for the following domains.
"
+ 'content_message': gettext("You are going to request certificates for the following domains.
"
"This operation is safe to run multiple times, "
"existing certificates will not be regenerated. "
"Also notice that let's encrypt does not currently support wildcard certificates.") + content_error,
diff --git a/orchestra/contrib/letsencrypt/forms.py b/orchestra/contrib/letsencrypt/forms.py
index ef8cbf39..9d1db1dc 100644
--- a/orchestra/contrib/letsencrypt/forms.py
+++ b/orchestra/contrib/letsencrypt/forms.py
@@ -1,6 +1,6 @@
from django import forms
from django.core.exceptions import ValidationError
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from .helpers import is_valid_domain
diff --git a/orchestra/contrib/lists/admin.py b/orchestra/contrib/lists/admin.py
index 8332fe10..d356d726 100644
--- a/orchestra/contrib/lists/admin.py
+++ b/orchestra/contrib/lists/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib.auth.admin import UserAdmin
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable, enable
diff --git a/orchestra/contrib/lists/backends.py b/orchestra/contrib/lists/backends.py
index c9e6f1dc..b6d4dc97 100644
--- a/orchestra/contrib/lists/backends.py
+++ b/orchestra/contrib/lists/backends.py
@@ -1,6 +1,6 @@
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
from orchestra.contrib.resources import ServiceMonitor
@@ -18,7 +18,7 @@ class MailmanVirtualDomainController(ServiceController):
doc_settings = (settings,
('LISTS_VIRTUAL_ALIAS_DOMAINS_PATH',)
)
-
+
def is_hosted_domain(self, domain):
""" whether or not domain MX points to this server """
return domain.has_default_mx()
@@ -48,11 +48,11 @@ class MailmanVirtualDomainController(ServiceController):
def save(self, mail_list):
context = self.get_context(mail_list)
- #self.include_virtual_alias_domain(context)
+ self.include_virtual_alias_domain(context)
def delete(self, mail_list):
context = self.get_context(mail_list)
- #self.exclude_virtual_alias_domain(context)
+ self.exclude_virtual_alias_domain(context)
def commit(self):
context = self.get_context_files()
@@ -100,29 +100,70 @@ class MailmanController(MailmanVirtualDomainController):
aliases = ['# %(banner)s' % context]
for suffix in self.address_suffixes:
context['suffix'] = suffix
- # Because mailman doesn't properly handle lists aliases we need two virtual aliases
- aliases.append("%(address_name)s%(suffix)s@%(domain)s\t%(name)s%(suffix)s@grups.pangea.org" % context)
+ # Because mailman doesn't properly handle lists aliases we need virtual aliases
if context['address_name'] != context['name']:
- # And another with the original list name; Mailman generates links with it
- aliases.append("%(name)s%(suffix)s@%(domain)s\t%(name)s%(suffix)s" % context)
+ aliases.append("%(address_name)s%(suffix)s@%(domain)s\t%(name)s%(suffix)s@grups.pangea.org" % context)
return '\n'.join(aliases)
+
def save(self, mail_list):
context = self.get_context(mail_list)
+
# Create list
cmd = "/opt/mailman/venv/bin/python /usr/local/admin/orchestra_mailman3/save.py %(name)s %(admin)s %(address_name)s@%(domain)s" % context
if not mail_list.active:
cmd += ' --inactive'
self.append(cmd)
+ # Custom domain
+ if mail_list.address:
+ context.update({
+ 'aliases': self.get_virtual_aliases(context),
+ 'num_entries': 2 if context['address_name'] != context['name'] else 1,
+ })
+ self.append(textwrap.dedent("""\
+ # Create list alias for custom domain
+ aliases='%(aliases)s'
+ if ! grep '\s\s*%(name)s\s*$' %(virtual_alias)s > /dev/null; then
+ echo "${aliases}" >> %(virtual_alias)s
+ UPDATED_VIRTUAL_ALIAS=1
+ else
+ if grep -E '(%(address_name)s|%(name)s)@(%(address_domain)s|grups.pangea.org)' %(virtual_alias)s > /dev/null ; then
+ sed -i -e '/^.*%(name)s\(-admin\|-bounces\|-confirm\|-join\|-leave\|-owner\|-request\|-subscribe\|-unsubscribe\|@\).*$/d' \\
+ -e '/# .*%(name)s$/d' %(virtual_alias)s
+ echo "${aliases}" >> %(virtual_alias)s
+ UPDATED_VIRTUAL_ALIAS=1
+ fi
+ fi """) % context
+ )
+ else:
+ self.append(textwrap.dedent("""\
+ # Cleanup possible ex-custom domain
+ if grep '\s\s*%(name)s\s*$' %(virtual_alias)s > /dev/null; then
+ #sed -i "/^.*\s%(name)s\s*$/d" %(virtual_alias)s
+ sed -i -e '/^.*%(name)s\(-admin\|-bounces\|-confirm\|-join\|-leave\|-owner\|-request\|-subscribe\|-unsubscribe\|@\).*$/d' \\
+ -e '/# .*%(name)s$/d' %(virtual_alias)s
+ fi""") % context
+ )
+
+
def delete(self, mail_list):
context = self.get_context(mail_list)
+
+ # Custom domain delete
+ self.append(textwrap.dedent("""\
+ # Cleanup possible ex-custom domain
+ if grep '\s\s*%(name)s\s*$' %(virtual_alias)s > /dev/null; then
+ sed -i -e '/^.*%(name)s\(-admin\|-bounces\|-confirm\|-join\|-leave\|-owner\|-request\|-subscribe\|-unsubscribe\|@\).*$/d' \\
+ -e '/# .*%(name)s$/d' %(virtual_alias)s
+ fi""") % context
+ )
+
# Delete list
- cmd = "/opt/mailman/venv/bin/python /usr/local/admin/orchestra_mailman3/delete.py %(name)s %(admin)s %(address_name)s@%(domain)s" % context
- if not mail_list.active:
- cmd += ' --inactive'
+ cmd = "/opt/mailman/venv/bin/python /usr/local/admin/orchestra_mailman3/delete.py %(name)s" % context
self.append(cmd)
-
+
+
def commit(self):
pass
diff --git a/orchestra/contrib/lists/filters.py b/orchestra/contrib/lists/filters.py
index 5271153d..8ba06ebb 100644
--- a/orchestra/contrib/lists/filters.py
+++ b/orchestra/contrib/lists/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class HasCustomAddressListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/lists/models.py b/orchestra/contrib/lists/models.py
index a78580d9..8ac33723 100644
--- a/orchestra/contrib/lists/models.py
+++ b/orchestra/contrib/lists/models.py
@@ -1,7 +1,7 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core.validators import validate_name
diff --git a/orchestra/contrib/lists/serializers.py b/orchestra/contrib/lists/serializers.py
index 317e3e77..593612ad 100644
--- a/orchestra/contrib/lists/serializers.py
+++ b/orchestra/contrib/lists/serializers.py
@@ -1,6 +1,6 @@
from django.core.validators import RegexValidator
from django.forms import widgets
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.api.serializers import SetPasswordHyperlinkedSerializer, RelatedHyperlinkedModelSerializer
diff --git a/orchestra/contrib/lists/settings.py b/orchestra/contrib/lists/settings.py
index 147b3d0e..9d5e25ae 100644
--- a/orchestra/contrib/lists/settings.py
+++ b/orchestra/contrib/lists/settings.py
@@ -21,20 +21,20 @@ LISTS_LIST_URL = Setting('LISTS_LIST_URL',
LISTS_MAILMAN_POST_LOG_PATH = Setting('LISTS_MAILMAN_POST_LOG_PATH',
- '/var/log/mailman/post'
+ '/var/log/mailman3/smtp'
)
LISTS_MAILMAN_ROOT_DIR = Setting('LISTS_MAILMAN_ROOT_DIR',
- '/var/lib/mailman'
+ '/var/lib/mailman3'
)
LISTS_VIRTUAL_ALIAS_PATH = Setting('LISTS_VIRTUAL_ALIAS_PATH',
- '/etc/postfix/mailman_virtual_aliases'
+ '/etc/postfix/mailman3_virtusertable'
)
LISTS_VIRTUAL_ALIAS_DOMAINS_PATH = Setting('LISTS_VIRTUAL_ALIAS_DOMAINS_PATH',
- '/etc/postfix/mailman_virtual_domains'
+ '/etc/postfix/mailman3_virtdomains'
)
diff --git a/orchestra/contrib/mailboxes/admin.py b/orchestra/contrib/mailboxes/admin.py
index 3314b1db..d1094d3f 100644
--- a/orchestra/contrib/mailboxes/admin.py
+++ b/orchestra/contrib/mailboxes/admin.py
@@ -8,7 +8,7 @@ from django.db.models import F, Count, Value as V
from django.db.models.functions import Concat
from django.utils.html import format_html, format_html_join
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable, enable
diff --git a/orchestra/contrib/mailboxes/backends.py b/orchestra/contrib/mailboxes/backends.py
index 59904e02..c15c42fb 100644
--- a/orchestra/contrib/mailboxes/backends.py
+++ b/orchestra/contrib/mailboxes/backends.py
@@ -4,7 +4,7 @@ import re
import textwrap
from django.core.exceptions import ObjectDoesNotExist
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.resources import ServiceMonitor
@@ -437,15 +437,20 @@ class DovecotMaildirDisk(ServiceMonitor):
def prepare(self):
super().prepare()
current_date = self.current_date.strftime("%Y-%m-%d %H:%M:%S %Z")
+ # self.append(textwrap.dedent("""\
+ # function monitor () {
+ # awk 'BEGIN { size = 0 } NR > 1 { size += $1 } END { print size }' $1 || echo 0
+ # }"""))
self.append(textwrap.dedent("""\
function monitor () {
- awk 'BEGIN { size = 0 } NR > 1 { size += $1 } END { print size }' $1 || echo 0
+ SIZE=$(du -sb $1/Maildir/ 2> /dev/null || echo 0) && echo $SIZE | awk '{print $1}'
}"""))
def monitor(self, mailbox):
context = self.get_context(mailbox)
- self.append("echo %(object_id)s $(monitor %(maildir_path)s)" % context)
-
+ # self.append("echo %(object_id)s $(monitor %(maildir_path)s)" % context)
+ self.append("echo %(object_id)s $(monitor %(home)s)" % context)
+
def get_context(self, mailbox):
context = {
'home': mailbox.get_home(),
diff --git a/orchestra/contrib/mailboxes/filters.py b/orchestra/contrib/mailboxes/filters.py
index 23c2f163..2c1dd603 100644
--- a/orchestra/contrib/mailboxes/filters.py
+++ b/orchestra/contrib/mailboxes/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class HasMailboxListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/mailboxes/forms.py b/orchestra/contrib/mailboxes/forms.py
index b4a5372d..522b608e 100644
--- a/orchestra/contrib/mailboxes/forms.py
+++ b/orchestra/contrib/mailboxes/forms.py
@@ -2,7 +2,7 @@ from django import forms
from django.contrib.admin import widgets
from django.core.exceptions import ValidationError
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.forms import UserCreationForm, UserChangeForm
from orchestra.utils.python import AttrDict
diff --git a/orchestra/contrib/mailboxes/models.py b/orchestra/contrib/mailboxes/models.py
index a38078ca..7122b5e1 100644
--- a/orchestra/contrib/mailboxes/models.py
+++ b/orchestra/contrib/mailboxes/models.py
@@ -6,7 +6,7 @@ from django.contrib.auth.hashers import make_password
from django.core.validators import RegexValidator, ValidationError
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from . import validators, settings
diff --git a/orchestra/contrib/mailboxes/settings.py b/orchestra/contrib/mailboxes/settings.py
index f8dccc50..c9412754 100644
--- a/orchestra/contrib/mailboxes/settings.py
+++ b/orchestra/contrib/mailboxes/settings.py
@@ -3,7 +3,7 @@ import textwrap
from django.utils.functional import lazy
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
from orchestra.core.validators import validate_name
diff --git a/orchestra/contrib/mailboxes/validators.py b/orchestra/contrib/mailboxes/validators.py
index 447a5feb..5a33b16a 100644
--- a/orchestra/contrib/mailboxes/validators.py
+++ b/orchestra/contrib/mailboxes/validators.py
@@ -3,7 +3,7 @@ import os
import re
from django.core.validators import ValidationError, EmailValidator
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.utils import paths
from orchestra.utils.sys import run
diff --git a/orchestra/contrib/mailer/admin.py b/orchestra/contrib/mailer/admin.py
index 3e7371d5..9d508c11 100644
--- a/orchestra/contrib/mailer/admin.py
+++ b/orchestra/contrib/mailer/admin.py
@@ -8,7 +8,7 @@ from django.db.models import Count
from django.shortcuts import redirect
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.utils import admin_link, admin_colored, admin_date, wrap_admin_view
@@ -115,7 +115,7 @@ class MessageAdmin(ExtendedModelAdmin):
display_to.short_description = _("To")
def get_urls(self):
- from django.conf.urls import url
+ from django.urls import re_path as url
urls = super().get_urls()
info = self.model._meta.app_label, self.model._meta.model_name
urls.insert(0,
diff --git a/orchestra/contrib/mailer/engine.py b/orchestra/contrib/mailer/engine.py
index 27a649ed..898f2041 100644
--- a/orchestra/contrib/mailer/engine.py
+++ b/orchestra/contrib/mailer/engine.py
@@ -1,3 +1,4 @@
+
import smtplib
from datetime import timedelta
from socket import error as SocketError
@@ -5,7 +6,6 @@ from socket import error as SocketError
from django.core.mail import get_connection
from django.db.models import Q
from django.utils import timezone
-from django.utils.encoding import smart_str
from orchestra.utils.sys import LockFile, OperationLocked
@@ -31,7 +31,7 @@ def send_message(message, connection=None, bulk=settings.MAILER_BULK_MESSAGES):
return
error = None
try:
- connection.connection.sendmail(message.from_address, [message.to_address], smart_str(message.content))
+ connection.connection.sendmail(message.from_address, [message.to_address], message.content.encode())
except (SocketError,
smtplib.SMTPSenderRefused,
smtplib.SMTPRecipientsRefused,
diff --git a/orchestra/contrib/mailer/models.py b/orchestra/contrib/mailer/models.py
index f7c61aff..c905768c 100644
--- a/orchestra/contrib/mailer/models.py
+++ b/orchestra/contrib/mailer/models.py
@@ -1,5 +1,5 @@
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from . import settings
diff --git a/orchestra/contrib/mailer/settings.py b/orchestra/contrib/mailer/settings.py
index 0cd6da8a..e040a523 100644
--- a/orchestra/contrib/mailer/settings.py
+++ b/orchestra/contrib/mailer/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
diff --git a/orchestra/contrib/mailer/templates/admin/mailer/message/change_list.html b/orchestra/contrib/mailer/templates/admin/mailer/message/change_list.html
index 93f17d12..d39ecb99 100644
--- a/orchestra/contrib/mailer/templates/admin/mailer/message/change_list.html
+++ b/orchestra/contrib/mailer/templates/admin/mailer/message/change_list.html
@@ -1,5 +1,5 @@
{% extends "admin/change_list.html" %}
-{% load i18n admin_urls admin_static admin_list %}
+{% load i18n admin_urls static admin_list %}
{% block object-tools-items %}
diff --git a/orchestra/contrib/miscellaneous/admin.py b/orchestra/contrib/miscellaneous/admin.py
index ff4920e6..2fce1981 100644
--- a/orchestra/contrib/miscellaneous/admin.py
+++ b/orchestra/contrib/miscellaneous/admin.py
@@ -4,7 +4,7 @@ from django.urls import reverse
from django.db import models
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.actions import disable, enable
diff --git a/orchestra/contrib/miscellaneous/models.py b/orchestra/contrib/miscellaneous/models.py
index e5fe5f0f..2a54983c 100644
--- a/orchestra/contrib/miscellaneous/models.py
+++ b/orchestra/contrib/miscellaneous/models.py
@@ -1,6 +1,6 @@
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core.validators import validate_name
from orchestra.models.fields import NullableCharField
diff --git a/orchestra/contrib/orchestration/actions.py b/orchestra/contrib/orchestration/actions.py
index 3f8a0b39..042f19ad 100644
--- a/orchestra/contrib/orchestration/actions.py
+++ b/orchestra/contrib/orchestration/actions.py
@@ -4,7 +4,7 @@ from django.contrib import messages
from django.contrib.admin import helpers
from django.shortcuts import render
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.admin.utils import get_object_from_url, change_url
from orchestra.contrib.orchestration.helpers import message_user
diff --git a/orchestra/contrib/orchestration/admin.py b/orchestra/contrib/orchestration/admin.py
index 4f5ddc4b..703fba84 100644
--- a/orchestra/contrib/orchestration/admin.py
+++ b/orchestra/contrib/orchestration/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin, messages
from django.utils.html import escape
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangeViewActionsMixin
from orchestra.admin.utils import admin_link, admin_date, admin_colored, display_mono, display_code
diff --git a/orchestra/contrib/orchestration/backends.py b/orchestra/contrib/orchestration/backends.py
index b2f22267..f1a04fe3 100644
--- a/orchestra/contrib/orchestration/backends.py
+++ b/orchestra/contrib/orchestration/backends.py
@@ -4,7 +4,7 @@ from functools import partial
from django.apps import apps
from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra import plugins
diff --git a/orchestra/contrib/orchestration/helpers.py b/orchestra/contrib/orchestration/helpers.py
index 768e9997..68296ab2 100644
--- a/orchestra/contrib/orchestration/helpers.py
+++ b/orchestra/contrib/orchestration/helpers.py
@@ -5,7 +5,7 @@ from django.core.mail import mail_admins
from django.urls import reverse, NoReverseMatch
from django.utils.html import escape
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra import settings as orchestra_settings
from orchestra.admin.utils import change_url
@@ -125,7 +125,7 @@ def get_messages(logs):
async_url = get_backend_url(async_ids)
async_msg = ''
if run_async:
- async_msg = ungettext(
+ async_msg = ngettext(
_('{name} is running on the background'),
_('{run_async} backends are running on the background'),
run_async)
@@ -133,7 +133,7 @@ def get_messages(logs):
if total == 1:
msg = _('{name} has fail to execute')
else:
- msg = ungettext(
+ msg = ngettext(
_('{errors} out of {total} backends has fail to execute'),
_('{errors} out of {total} backends have fail to execute'),
errors)
@@ -147,13 +147,13 @@ def get_messages(logs):
if total == 1:
msg = _('{name} has been executed')
else:
- msg = ungettext(
+ msg = ngettext(
_('{successes} out of {total} backends has been executed'),
_('{successes} out of {total} backends have been executed'),
successes)
msg += ', ' + str(async_msg)
else:
- msg = ungettext(
+ msg = ngettext(
_('{name} has been executed'),
_('{total} backends have been executed'),
total)
diff --git a/orchestra/contrib/orchestration/models.py b/orchestra/contrib/orchestration/models.py
index 14e8db2d..4f8606d8 100644
--- a/orchestra/contrib/orchestration/models.py
+++ b/orchestra/contrib/orchestration/models.py
@@ -5,10 +5,10 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import models
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.functional import cached_property
from django.utils.module_loading import autodiscover_modules
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core.validators import validate_ip_address, validate_hostname, OrValidator
from orchestra.models.fields import NullableCharField, MultiSelectField
@@ -128,7 +128,7 @@ class BackendOperationQuerySet(models.QuerySet):
def create(self, **kwargs):
instance = kwargs.get('instance')
if instance and 'instance_repr' not in kwargs:
- kwargs['instance_repr'] = force_text(instance)[:256]
+ kwargs['instance_repr'] = force_str(instance)[:256]
return super(BackendOperationQuerySet, self).create(**kwargs)
@@ -207,7 +207,7 @@ class Route(models.Model):
run_async = models.BooleanField(default=False,
help_text=_("Whether or not block the request/response cycle waitting this backend to "
"finish its execution. Usually you want slave servers to run asynchronously."))
- async_actions = MultiSelectField(max_length=256, blank=True,
+ async_actions = MultiSelectField(max_length=256, blank=True, choices=[],
help_text=_("Specify individual actions to be executed asynchronoulsy."))
# method = models.CharField(_("method"), max_lenght=32, choices=method_choices,
# default=MethodBackend.get_default())
diff --git a/orchestra/contrib/orchestration/settings.py b/orchestra/contrib/orchestration/settings.py
index d74c5314..fee41c42 100644
--- a/orchestra/contrib/orchestration/settings.py
+++ b/orchestra/contrib/orchestration/settings.py
@@ -1,6 +1,6 @@
from os import path
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
diff --git a/orchestra/contrib/orchestration/signals.py b/orchestra/contrib/orchestration/signals.py
index ab26858b..a49f493b 100644
--- a/orchestra/contrib/orchestration/signals.py
+++ b/orchestra/contrib/orchestration/signals.py
@@ -1,14 +1,14 @@
import django.dispatch
+pre_action = django.dispatch.Signal()
-pre_action = django.dispatch.Signal(providing_args=['backend', 'instance', 'action'])
+post_action = django.dispatch.Signal()
-post_action = django.dispatch.Signal(providing_args=['backend', 'instance', 'action'])
+pre_prepare = django.dispatch.Signal()
-pre_prepare = django.dispatch.Signal(providing_args=['backend'])
+post_prepare = django.dispatch.Signal()
-post_prepare = django.dispatch.Signal(providing_args=['backend'])
+pre_commit = django.dispatch.Signal()
-pre_commit = django.dispatch.Signal(providing_args=['backend'])
+post_commit = django.dispatch.Signal()
-post_commit = django.dispatch.Signal(providing_args=['backend'])
diff --git a/orchestra/contrib/orders/actions.py b/orchestra/contrib/orders/actions.py
index 5a91a3f7..ba2244ec 100644
--- a/orchestra/contrib/orders/actions.py
+++ b/orchestra/contrib/orders/actions.py
@@ -3,7 +3,7 @@ from django.urls import reverse
from django.db import transaction
from django.utils import timezone
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from django.shortcuts import render
from orchestra.admin.utils import change_url
@@ -95,7 +95,7 @@ class BillSelectedOrders(object):
url = reverse('admin:bills_bill_changelist')
ids = ','.join([str(b.id) for b in bills])
url += '?id__in=%s' % ids
- msg = ungettext(
+ msg = ngettext(
'One bill has been created.',
'{num} bills have been created.',
num).format(url=url, num=num)
@@ -126,7 +126,7 @@ def mark_as_ignored(modeladmin, request, queryset):
order.mark_as_ignored()
modeladmin.log_change(request, order, 'Marked as ignored')
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("Selected order has been marked as ignored."),
_("%i selected orders have been marked as ignored.") % num,
num)
@@ -140,7 +140,7 @@ def mark_as_not_ignored(modeladmin, request, queryset):
order.mark_as_not_ignored()
modeladmin.log_change(request, order, 'Marked as not ignored')
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("Selected order has been marked as not ignored."),
_("%i selected orders have been marked as not ignored.") % num,
num)
diff --git a/orchestra/contrib/orders/admin.py b/orchestra/contrib/orders/admin.py
index 43838e4f..3c3086b8 100644
--- a/orchestra/contrib/orders/admin.py
+++ b/orchestra/contrib/orders/admin.py
@@ -6,7 +6,7 @@ from django.db.models import Prefetch
from django.utils import timezone
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.utils import admin_link, admin_date, change_url
diff --git a/orchestra/contrib/orders/billing.py b/orchestra/contrib/orders/billing.py
index 650f8df5..a6daee33 100644
--- a/orchestra/contrib/orders/billing.py
+++ b/orchestra/contrib/orders/billing.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.bills.models import Invoice, Fee, ProForma
diff --git a/orchestra/contrib/orders/filters.py b/orchestra/contrib/orders/filters.py
index c0a54332..4693529f 100644
--- a/orchestra/contrib/orders/filters.py
+++ b/orchestra/contrib/orders/filters.py
@@ -4,8 +4,8 @@ from django.apps import apps
from django.contrib.admin import SimpleListFilter
from django.db.models import Q, Prefetch, F
from django.utils import timezone
-from django.utils.encoding import force_text
-from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import force_str
+from django.utils.translation import gettext_lazy as _
from . import settings
from .models import MetricStorage
@@ -118,7 +118,7 @@ class IgnoreOrderListFilter(SimpleListFilter):
""" Enable default selection different than All """
for lookup, title in self.lookup_choices:
title = title._proxy____args[0]
- selected = self.value() == force_text(lookup)
+ selected = self.value() == force_str(lookup)
if not selected and title == "Not ignored" and self.value() is None:
selected = True
# end of workaround
diff --git a/orchestra/contrib/orders/forms.py b/orchestra/contrib/orders/forms.py
index 2376e612..0dd9a0ab 100644
--- a/orchestra/contrib/orders/forms.py
+++ b/orchestra/contrib/orders/forms.py
@@ -2,7 +2,7 @@ from django import forms
from django.contrib.admin import widgets
from django.utils import timezone
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.forms import AdminFormMixin
from orchestra.admin.utils import change_url
diff --git a/orchestra/contrib/orders/models.py b/orchestra/contrib/orders/models.py
index 69e5fa3b..db6febc8 100644
--- a/orchestra/contrib/orders/models.py
+++ b/orchestra/contrib/orders/models.py
@@ -9,7 +9,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.models import queryset
from orchestra.utils.python import import_class
diff --git a/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html b/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html
index 878c116f..6dd023f6 100644
--- a/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html
+++ b/orchestra/contrib/orders/templates/admin/orders/order/bill_selected_options.html
@@ -1,5 +1,5 @@
{% extends "admin/base_site.html" %}
-{% load i18n l10n staticfiles admin_urls utils orders %}
+{% load i18n l10n static admin_urls utils orders %}
{% block extrastyle %}
{{ block.super }}
diff --git a/orchestra/contrib/payments/actions.py b/orchestra/contrib/payments/actions.py
index d2f5a433..ae531555 100644
--- a/orchestra/contrib/payments/actions.py
+++ b/orchestra/contrib/payments/actions.py
@@ -7,7 +7,7 @@ from django.db import transaction
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
from django.utils.text import capfirst
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.admin.decorators import action_with_confirmation
from orchestra.admin.utils import change_url
@@ -38,11 +38,11 @@ def process_transactions(modeladmin, request, queryset):
opts = modeladmin.model._meta
num = len(queryset)
context = {
- 'title': ungettext(
+ 'title': ngettext(
_("One selected transaction has been processed."),
_("%s Selected transactions have been processed.") % num,
num),
- 'content_message': ungettext(
+ 'content_message': ngettext(
_("The following transaction process has been generated, "
"you may want to save it on your computer now."),
_("The following %s transaction processes have been generated, "
@@ -63,7 +63,7 @@ def mark_as_executed(modeladmin, request, queryset):
transaction.mark_as_executed()
modeladmin.log_change(request, transaction, _("Executed"))
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("One selected transaction has been marked as executed."),
_("%s selected transactions have been marked as executed.") % num,
num)
@@ -79,7 +79,7 @@ def mark_as_secured(modeladmin, request, queryset):
transaction.mark_as_secured()
modeladmin.log_change(request, transaction, _("Secured"))
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("One selected transaction has been marked as secured."),
_("%s selected transactions have been marked as secured.") % num,
num)
@@ -95,7 +95,7 @@ def mark_as_rejected(modeladmin, request, queryset):
transaction.mark_as_rejected()
modeladmin.log_change(request, transaction, _("Rejected"))
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("One selected transaction has been marked as rejected."),
_("%s selected transactions have been marked as rejected.") % num,
num)
@@ -134,7 +134,7 @@ def mark_process_as_executed(modeladmin, request, queryset):
process.mark_as_executed()
modeladmin.log_change(request, process, _("Executed"))
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("One selected process has been marked as executed."),
_("%s selected processes have been marked as executed.") % num,
num)
@@ -150,7 +150,7 @@ def abort(modeladmin, request, queryset):
process.abort()
modeladmin.log_change(request, process, _("Aborted"))
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("One selected process has been aborted."),
_("%s selected processes have been aborted.") % num,
num)
@@ -166,7 +166,7 @@ def commit(modeladmin, request, queryset):
transaction.mark_as_rejected()
modeladmin.log_change(request, transaction, _("Rejected"))
num = len(queryset)
- msg = ungettext(
+ msg = ngettext(
_("One selected transaction has been marked as rejected."),
_("%s selected transactions have been marked as rejected.") % num,
num)
diff --git a/orchestra/contrib/payments/admin.py b/orchestra/contrib/payments/admin.py
index 016543ac..e134c2e5 100644
--- a/orchestra/contrib/payments/admin.py
+++ b/orchestra/contrib/payments/admin.py
@@ -3,7 +3,7 @@ from django.urls import reverse
from django.http import HttpResponseRedirect
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ChangeViewActionsMixin, ExtendedModelAdmin
from orchestra.admin.utils import admin_colored, admin_link, admin_date
diff --git a/orchestra/contrib/payments/helpers.py b/orchestra/contrib/payments/helpers.py
index b6645d53..59163a09 100644
--- a/orchestra/contrib/payments/helpers.py
+++ b/orchestra/contrib/payments/helpers.py
@@ -1,5 +1,5 @@
from django.contrib import messages
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from .models import Transaction
@@ -29,7 +29,7 @@ def post_delete_processes(modeladmin, request, related_transactions):
transaction.save(update_fields=('state', 'modified_at'))
num += 1
modeladmin.log_change(request, transaction, _("Unprocessed"))
- messages.success(request, ungettext(
+ messages.success(request, ngettext(
"One related transaction has been marked as waitting for processing",
"%i related transactions have been marked as waitting for processing." % num,
num
diff --git a/orchestra/contrib/payments/methods/creditcard.py b/orchestra/contrib/payments/methods/creditcard.py
index 942b6d30..14e5851c 100644
--- a/orchestra/contrib/payments/methods/creditcard.py
+++ b/orchestra/contrib/payments/methods/creditcard.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.plugins.forms import PluginDataForm
diff --git a/orchestra/contrib/payments/methods/sepadirectdebit.py b/orchestra/contrib/payments/methods/sepadirectdebit.py
index 78ddd8fe..8ce1bf31 100644
--- a/orchestra/contrib/payments/methods/sepadirectdebit.py
+++ b/orchestra/contrib/payments/methods/sepadirectdebit.py
@@ -5,7 +5,7 @@ from io import StringIO
from django import forms
from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from django_iban.validators import IBANValidator, IBAN_COUNTRY_CODE_LENGTH
from rest_framework import serializers
diff --git a/orchestra/contrib/payments/models.py b/orchestra/contrib/payments/models.py
index 4d7770c8..9617ce40 100644
--- a/orchestra/contrib/payments/models.py
+++ b/orchestra/contrib/payments/models.py
@@ -1,7 +1,7 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from orchestra.models.fields import PrivateFileField
diff --git a/orchestra/contrib/payments/settings.py b/orchestra/contrib/payments/settings.py
index 68d27511..65e5702d 100644
--- a/orchestra/contrib/payments/settings.py
+++ b/orchestra/contrib/payments/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
diff --git a/orchestra/contrib/plans/admin.py b/orchestra/contrib/plans/admin.py
index df75ca24..0a9ebacb 100644
--- a/orchestra/contrib/plans/admin.py
+++ b/orchestra/contrib/plans/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin
from django.urls import reverse
from django.db import models
from django.utils.html import format_html
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.utils import insertattr, admin_link
diff --git a/orchestra/contrib/plans/models.py b/orchestra/contrib/plans/models.py
index 22b698f3..429ecc39 100644
--- a/orchestra/contrib/plans/models.py
+++ b/orchestra/contrib/plans/models.py
@@ -4,7 +4,7 @@ from django.core.validators import ValidationError
from django.db import models
from django.db.models import Q
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core.validators import validate_name
from orchestra.models import queryset
diff --git a/orchestra/contrib/plans/ratings.py b/orchestra/contrib/plans/ratings.py
index e55c7a27..1c1cd9e3 100644
--- a/orchestra/contrib/plans/ratings.py
+++ b/orchestra/contrib/plans/ratings.py
@@ -1,6 +1,6 @@
import sys
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.utils.python import AttrDict
diff --git a/orchestra/contrib/resources/actions.py b/orchestra/contrib/resources/actions.py
index c355da2b..3120213b 100644
--- a/orchestra/contrib/resources/actions.py
+++ b/orchestra/contrib/resources/actions.py
@@ -1,7 +1,7 @@
from django.urls import reverse
from django.shortcuts import redirect, render
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
def run_monitor(modeladmin, request, queryset):
@@ -18,7 +18,7 @@ def run_monitor(modeladmin, request, queryset):
num = len(queryset)
# TODO listfilter by uuid: task.request.id + ?task_id__in=ids
link = reverse('admin:djcelery_taskstate_changelist')
- msg = ungettext(
+ msg = ngettext(
_("One selected resource has been scheduled for monitoring.") % link,
_("%s selected resource have been scheduled for monitoring.") % (num, link),
num)
diff --git a/orchestra/contrib/resources/admin.py b/orchestra/contrib/resources/admin.py
index b965c4ee..53f573ee 100644
--- a/orchestra/contrib/resources/admin.py
+++ b/orchestra/contrib/resources/admin.py
@@ -1,7 +1,7 @@
from urllib.parse import parse_qs
from django.apps import apps
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin, messages
from django.contrib.contenttypes.admin import GenericTabularInline
from django.contrib.contenttypes.forms import BaseGenericInlineFormSet
@@ -13,7 +13,7 @@ from django.templatetags.static import static
from django.utils.functional import cached_property
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.utils import insertattr, get_modeladmin, admin_link, admin_date
@@ -70,7 +70,7 @@ class ResourceAdmin(ExtendedModelAdmin):
if monitor not in backends:
not_routed.append(monitor)
if not_routed:
- messages.warning(request, ungettext(
+ messages.warning(request, ngettext(
_("%(not_routed)s monitor doesn't have any configured route."),
_("%(not_routed)s monitors don't have any configured route."),
len(not_routed),
diff --git a/orchestra/contrib/resources/aggregations.py b/orchestra/contrib/resources/aggregations.py
index 13d966cc..f43e7ffd 100644
--- a/orchestra/contrib/resources/aggregations.py
+++ b/orchestra/contrib/resources/aggregations.py
@@ -3,7 +3,7 @@ import decimal
import itertools
from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.utils.python import AttrDict
diff --git a/orchestra/contrib/resources/backends.py b/orchestra/contrib/resources/backends.py
index 2ca21c23..a997df5f 100644
--- a/orchestra/contrib/resources/backends.py
+++ b/orchestra/contrib/resources/backends.py
@@ -2,7 +2,7 @@ import datetime
from django.utils import timezone
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceBackend
diff --git a/orchestra/contrib/resources/filters.py b/orchestra/contrib/resources/filters.py
index 91ea81a3..fe8392cd 100644
--- a/orchestra/contrib/resources/filters.py
+++ b/orchestra/contrib/resources/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class ResourceDataListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/resources/forms.py b/orchestra/contrib/resources/forms.py
index 3099fc5f..75d5b85a 100644
--- a/orchestra/contrib/resources/forms.py
+++ b/orchestra/contrib/resources/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.forms import ReadOnlyFormMixin
from orchestra.forms.widgets import SpanWidget
diff --git a/orchestra/contrib/resources/models.py b/orchestra/contrib/resources/models.py
index 50c1b14a..7b1e0ff9 100644
--- a/orchestra/contrib/resources/models.py
+++ b/orchestra/contrib/resources/models.py
@@ -4,7 +4,7 @@ from django.apps import apps
from django.db import models
from django.utils import timezone
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from djcelery.models import PeriodicTask
from orchestra.core import validators
diff --git a/orchestra/contrib/resources/validators.py b/orchestra/contrib/resources/validators.py
index 606641cc..710fb5f5 100644
--- a/orchestra/contrib/resources/validators.py
+++ b/orchestra/contrib/resources/validators.py
@@ -1,5 +1,5 @@
from django.core.validators import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
def validate_scale(value):
diff --git a/orchestra/contrib/saas/admin.py b/orchestra/contrib/saas/admin.py
index cdf5088c..90176d87 100644
--- a/orchestra/contrib/saas/admin.py
+++ b/orchestra/contrib/saas/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin
from django.core.exceptions import ObjectDoesNotExist
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable, enable
diff --git a/orchestra/contrib/saas/backends/bscw.py b/orchestra/contrib/saas/backends/bscw.py
index a5fe95be..0d0a1156 100644
--- a/orchestra/contrib/saas/backends/bscw.py
+++ b/orchestra/contrib/saas/backends/bscw.py
@@ -1,6 +1,6 @@
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
diff --git a/orchestra/contrib/saas/backends/dokuwikimu.py b/orchestra/contrib/saas/backends/dokuwikimu.py
index 411ca831..21a4d44e 100644
--- a/orchestra/contrib/saas/backends/dokuwikimu.py
+++ b/orchestra/contrib/saas/backends/dokuwikimu.py
@@ -3,7 +3,7 @@ import os
import textwrap
from urllib.parse import urlparse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.utils.python import random_ascii
diff --git a/orchestra/contrib/saas/backends/drupalmu.py b/orchestra/contrib/saas/backends/drupalmu.py
index bfa060cd..944903c9 100644
--- a/orchestra/contrib/saas/backends/drupalmu.py
+++ b/orchestra/contrib/saas/backends/drupalmu.py
@@ -1,7 +1,7 @@
import os
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
diff --git a/orchestra/contrib/saas/backends/gitlab.py b/orchestra/contrib/saas/backends/gitlab.py
index e015624b..042c82ae 100644
--- a/orchestra/contrib/saas/backends/gitlab.py
+++ b/orchestra/contrib/saas/backends/gitlab.py
@@ -1,7 +1,7 @@
import json
import requests
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
diff --git a/orchestra/contrib/saas/backends/moodle.py b/orchestra/contrib/saas/backends/moodle.py
index 339462db..d942675e 100644
--- a/orchestra/contrib/saas/backends/moodle.py
+++ b/orchestra/contrib/saas/backends/moodle.py
@@ -1,7 +1,7 @@
import textwrap
from urllib.parse import urlparse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
diff --git a/orchestra/contrib/saas/backends/nextcloud.py b/orchestra/contrib/saas/backends/nextcloud.py
index f4302ef6..17df098f 100644
--- a/orchestra/contrib/saas/backends/nextcloud.py
+++ b/orchestra/contrib/saas/backends/nextcloud.py
@@ -6,7 +6,7 @@ import xml.etree.ElementTree as ET
from urllib.parse import urlparse
import requests
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.resources import ServiceMonitor
@@ -33,7 +33,7 @@ class NextCloudAPIMixin(object):
def api_call(self, action, url_path, *args, **kwargs):
BASE_URL = settings.SAAS_NEXTCLOUD_API_URL.rstrip('/')
url = '/'.join((BASE_URL, url_path))
- response = action(url, headers={'OCS-APIRequest':'true'}, *args, **kwargs)
+ response = action(url, headers={'OCS-APIRequest':'true'}, verify=False, *args, **kwargs)
self.validate_response(response)
return response
diff --git a/orchestra/contrib/saas/backends/owncloud.py b/orchestra/contrib/saas/backends/owncloud.py
index b9544f68..a6496a42 100644
--- a/orchestra/contrib/saas/backends/owncloud.py
+++ b/orchestra/contrib/saas/backends/owncloud.py
@@ -6,7 +6,7 @@ import xml.etree.ElementTree as ET
from urllib.parse import urlparse
import requests
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.resources import ServiceMonitor
diff --git a/orchestra/contrib/saas/backends/phplist.py b/orchestra/contrib/saas/backends/phplist.py
index 43e73220..2b2992e3 100644
--- a/orchestra/contrib/saas/backends/phplist.py
+++ b/orchestra/contrib/saas/backends/phplist.py
@@ -4,7 +4,7 @@ import sys
import textwrap
import requests
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.resources import ServiceMonitor
diff --git a/orchestra/contrib/saas/backends/wordpressmu.py b/orchestra/contrib/saas/backends/wordpressmu.py
index 6dcbf8a9..7a8e75d8 100644
--- a/orchestra/contrib/saas/backends/wordpressmu.py
+++ b/orchestra/contrib/saas/backends/wordpressmu.py
@@ -6,7 +6,7 @@ from functools import partial
from urllib.parse import urlparse
import requests
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
diff --git a/orchestra/contrib/saas/filters.py b/orchestra/contrib/saas/filters.py
index 3bada2b3..51716780 100644
--- a/orchestra/contrib/saas/filters.py
+++ b/orchestra/contrib/saas/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class CustomURLListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/saas/forms.py b/orchestra/contrib/saas/forms.py
index d7292fd7..a1d9970f 100644
--- a/orchestra/contrib/saas/forms.py
+++ b/orchestra/contrib/saas/forms.py
@@ -1,7 +1,7 @@
from django import forms
from django.core.exceptions import ObjectDoesNotExist
from django.core.validators import RegexValidator
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import change_url
from orchestra.core import validators
diff --git a/orchestra/contrib/saas/models.py b/orchestra/contrib/saas/models.py
index c8a31f60..967bf7b8 100644
--- a/orchestra/contrib/saas/models.py
+++ b/orchestra/contrib/saas/models.py
@@ -1,6 +1,6 @@
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from orchestra.core import validators
diff --git a/orchestra/contrib/saas/serializers.py b/orchestra/contrib/saas/serializers.py
index 6992e5f7..a0da1a17 100644
--- a/orchestra/contrib/saas/serializers.py
+++ b/orchestra/contrib/saas/serializers.py
@@ -1,6 +1,6 @@
from django.forms import widgets
from django.core.validators import RegexValidator
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.api.serializers import SetPasswordHyperlinkedSerializer
diff --git a/orchestra/contrib/saas/services/bscw.py b/orchestra/contrib/saas/services/bscw.py
index 1afd119e..7fef1cda 100644
--- a/orchestra/contrib/saas/services/bscw.py
+++ b/orchestra/contrib/saas/services/bscw.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from .. import settings
diff --git a/orchestra/contrib/saas/services/dokuwiki.py b/orchestra/contrib/saas/services/dokuwiki.py
index 1235de84..5195f848 100644
--- a/orchestra/contrib/saas/services/dokuwiki.py
+++ b/orchestra/contrib/saas/services/dokuwiki.py
@@ -1,7 +1,7 @@
from urllib.parse import urlparse
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .options import SoftwareService
from .. import settings
diff --git a/orchestra/contrib/saas/services/gitlab.py b/orchestra/contrib/saas/services/gitlab.py
index 1586a77f..b8d62cfa 100644
--- a/orchestra/contrib/saas/services/gitlab.py
+++ b/orchestra/contrib/saas/services/gitlab.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.forms import widgets
diff --git a/orchestra/contrib/saas/services/helpers.py b/orchestra/contrib/saas/services/helpers.py
index a08855fe..0deb36f5 100644
--- a/orchestra/contrib/saas/services/helpers.py
+++ b/orchestra/contrib/saas/services/helpers.py
@@ -2,7 +2,7 @@ from collections import defaultdict
from urllib.parse import urlparse
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.websites.models import Website, WebsiteDirective, Content
from orchestra.contrib.websites.validators import validate_domain_protocol
diff --git a/orchestra/contrib/saas/services/moodle.py b/orchestra/contrib/saas/services/moodle.py
index a059550b..2b6580e4 100644
--- a/orchestra/contrib/saas/services/moodle.py
+++ b/orchestra/contrib/saas/services/moodle.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.forms.widgets import SpanWidget
diff --git a/orchestra/contrib/saas/services/nextcloud.py b/orchestra/contrib/saas/services/nextcloud.py
index 3398f0da..2027352e 100644
--- a/orchestra/contrib/saas/services/nextcloud.py
+++ b/orchestra/contrib/saas/services/nextcloud.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from .. import settings
diff --git a/orchestra/contrib/saas/services/options.py b/orchestra/contrib/saas/services/options.py
index 168aecce..37413a89 100644
--- a/orchestra/contrib/saas/services/options.py
+++ b/orchestra/contrib/saas/services/options.py
@@ -4,7 +4,7 @@ from functools import lru_cache
from urllib.parse import urlparse
from django.core.exceptions import ValidationError, ObjectDoesNotExist
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra import plugins
from orchestra.contrib.databases.models import Database, DatabaseUser
diff --git a/orchestra/contrib/saas/services/owncloud.py b/orchestra/contrib/saas/services/owncloud.py
index 2f850f07..2a6d1210 100644
--- a/orchestra/contrib/saas/services/owncloud.py
+++ b/orchestra/contrib/saas/services/owncloud.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from .. import settings
diff --git a/orchestra/contrib/saas/services/phplist.py b/orchestra/contrib/saas/services/phplist.py
index 7b803f04..9b97fe78 100644
--- a/orchestra/contrib/saas/services/phplist.py
+++ b/orchestra/contrib/saas/services/phplist.py
@@ -4,7 +4,7 @@ from django.core.exceptions import ValidationError
from django.urls import reverse
from django.db.models import Q
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.mailboxes.models import Mailbox
from orchestra.forms.widgets import SpanWidget
diff --git a/orchestra/contrib/saas/services/seafile.py b/orchestra/contrib/saas/services/seafile.py
index 3e7ea594..bc29a42d 100644
--- a/orchestra/contrib/saas/services/seafile.py
+++ b/orchestra/contrib/saas/services/seafile.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from .. import settings
diff --git a/orchestra/contrib/saas/services/wordpress.py b/orchestra/contrib/saas/services/wordpress.py
index 1e4d3f39..141bb488 100644
--- a/orchestra/contrib/saas/services/wordpress.py
+++ b/orchestra/contrib/saas/services/wordpress.py
@@ -1,6 +1,6 @@
from django import forms
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.forms import widgets
diff --git a/orchestra/contrib/saas/settings.py b/orchestra/contrib/saas/settings.py
index af768867..837d1e1c 100644
--- a/orchestra/contrib/saas/settings.py
+++ b/orchestra/contrib/saas/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
from orchestra.core.validators import validate_ip_address
diff --git a/orchestra/contrib/saas/validators.py b/orchestra/contrib/saas/validators.py
index ed9c7287..ac21bb88 100644
--- a/orchestra/contrib/saas/validators.py
+++ b/orchestra/contrib/saas/validators.py
@@ -1,5 +1,5 @@
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.utils.apps import isinstalled
diff --git a/orchestra/contrib/services/actions.py b/orchestra/contrib/services/actions.py
index 96d38e3d..4e48b2d8 100644
--- a/orchestra/contrib/services/actions.py
+++ b/orchestra/contrib/services/actions.py
@@ -4,7 +4,7 @@ from django.db import transaction
from django.shortcuts import render, redirect
from django.template.response import TemplateResponse
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import get_object_from_url
diff --git a/orchestra/contrib/services/admin.py b/orchestra/contrib/services/admin.py
index ecbe1e2d..2f4b835f 100644
--- a/orchestra/contrib/services/admin.py
+++ b/orchestra/contrib/services/admin.py
@@ -1,11 +1,11 @@
from django import forms
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib import admin
from django.urls import reverse
from django.template.response import TemplateResponse
from django.utils import timezone
from django.utils.html import format_html
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ChangeViewActionsMixin
from orchestra.admin.actions import disable, enable
diff --git a/orchestra/contrib/services/handlers.py b/orchestra/contrib/services/handlers.py
index af2671bb..64ceaf84 100644
--- a/orchestra/contrib/services/handlers.py
+++ b/orchestra/contrib/services/handlers.py
@@ -8,7 +8,7 @@ from dateutil import relativedelta
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.utils import timezone, translation
-from django.utils.translation import ugettext, ugettext_lazy as _
+from django.utils.translation import gettext, gettext_lazy as _
from orchestra import plugins
from orchestra.utils.humanize import text2int
@@ -34,11 +34,13 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
self.service = service
def __getattr__(self, attr):
+ if attr.startswith('__'):
+ raise AttributeError(f'{self} does not have attribute {attr}')
return getattr(self.service, attr)
@classmethod
def get_choices(cls):
- choices = super(ServiceHandler, cls).get_choices()
+ choices = super().get_choices()
return [('', _("Default"))] + choices
def validate_content_type(self, service):
@@ -75,7 +77,7 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
return {
'instance': instance,
'obj': instance,
- 'ugettext': ugettext,
+ 'gettext': gettext,
'handler': self,
'service': self.service,
instance._meta.model_name: instance,
@@ -134,7 +136,7 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
account = getattr(instance, 'account', instance)
with translation.override(account.language):
if not self.order_description:
- return '%s: %s' % (ugettext(self.description), instance)
+ return '%s: %s' % (gettext(self.description), instance)
return eval(self.order_description, safe_locals)
def get_billing_point(self, order, bp=None, **options):
diff --git a/orchestra/contrib/services/helpers.py b/orchestra/contrib/services/helpers.py
index 2e359d2d..68046597 100644
--- a/orchestra/contrib/services/helpers.py
+++ b/orchestra/contrib/services/helpers.py
@@ -1,5 +1,5 @@
from django.utils.text import format_lazy
-from django.utils.translation import ugettext_lazy
+from django.utils.translation import gettext_lazy
def get_chunks(porders, ini, end, ix=0):
@@ -141,7 +141,7 @@ def get_rate_methods_help_text(rate_class):
format_lazy('{}' * 4, *['
', method.verbose_name, ': ', method.help_text])
for method in rate_class.get_methods().values()
]
- prefix = ugettext_lazy("Algorithm used to interprete the rating table.")
+ prefix = gettext_lazy("Algorithm used to interprete the rating table.")
help_text_items = [prefix] + method_help_texts
return format_lazy(
'{}' * len(help_text_items),
diff --git a/orchestra/contrib/services/models.py b/orchestra/contrib/services/models.py
index 5dffcb48..0dc8bb80 100644
--- a/orchestra/contrib/services/models.py
+++ b/orchestra/contrib/services/models.py
@@ -7,7 +7,7 @@ from django.db import models
from django.apps import apps
from django.utils.functional import cached_property
from django.utils.module_loading import autodiscover_modules
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import caches, validators
from orchestra.utils.python import import_class
@@ -109,7 +109,7 @@ class Service(models.Model):
help_text=_(
"Python expression "
"used for generating the description for the bill lines of this services.
"
- "Defaults to '%s: %s' % (ugettext(handler.description), instance)"
+ "Defaults to '%s: %s' % (gettext(handler.description), instance)"
))
ignore_period = models.CharField(_("ignore period"), max_length=16, blank=True,
help_text=_("Period in which orders will be ignored if cancelled. "
diff --git a/orchestra/contrib/services/settings.py b/orchestra/contrib/services/settings.py
index 4a3f8634..5c783067 100644
--- a/orchestra/contrib/services/settings.py
+++ b/orchestra/contrib/services/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
diff --git a/orchestra/contrib/services/templates/admin/services/service/change_form.html b/orchestra/contrib/services/templates/admin/services/service/change_form.html
index 7d966e70..8a32497e 100644
--- a/orchestra/contrib/services/templates/admin/services/service/change_form.html
+++ b/orchestra/contrib/services/templates/admin/services/service/change_form.html
@@ -1,5 +1,5 @@
{% extends "orchestra/admin/change_form.html" %}
-{% load i18n admin_urls admin_static admin_modify utils %}
+{% load i18n admin_urls static admin_modify utils %}
{% block object-tools %}
diff --git a/orchestra/contrib/settings/admin.py b/orchestra/contrib/settings/admin.py
index 8761ae04..6cefcb08 100644
--- a/orchestra/contrib/settings/admin.py
+++ b/orchestra/contrib/settings/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin, messages
-from django.shortcuts import render_to_response
+from django.shortcuts import render
from django.views import generic
-from django.utils.translation import ngettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.contrib.settings import Setting
from orchestra.utils import sys
@@ -84,7 +84,7 @@ class SettingView(generic.edit.FormView):
_("%s changes successfully applied, orchestra is being restarted.") % n,
n),
}
- return render_to_response(self.reload_template_name, context)
+ return render(None, self.reload_template_name, context)
else:
messages.success(self.request, _("No changes have been detected."))
return super(SettingView, self).form_valid(form)
diff --git a/orchestra/contrib/settings/apps.py b/orchestra/contrib/settings/apps.py
index 17fa85c6..d9738ebb 100644
--- a/orchestra/contrib/settings/apps.py
+++ b/orchestra/contrib/settings/apps.py
@@ -1,7 +1,7 @@
from django.apps import AppConfig
from django.core.checks import register, Error
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import administration
diff --git a/orchestra/contrib/settings/forms.py b/orchestra/contrib/settings/forms.py
index 2b339584..164e6545 100644
--- a/orchestra/contrib/settings/forms.py
+++ b/orchestra/contrib/settings/forms.py
@@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError
from django.forms.formsets import formset_factory
from django.utils.functional import Promise
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.forms import ReadOnlyFormMixin, widgets
from orchestra.utils.python import format_exception
diff --git a/orchestra/contrib/settings/parser.py b/orchestra/contrib/settings/parser.py
index 4a06fe72..93923258 100644
--- a/orchestra/contrib/settings/parser.py
+++ b/orchestra/contrib/settings/parser.py
@@ -4,7 +4,7 @@ import json
import os
import re
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from django.utils.functional import Promise
from orchestra.utils.paths import get_project_dir
diff --git a/orchestra/contrib/settings/templates/admin/settings/reload.html b/orchestra/contrib/settings/templates/admin/settings/reload.html
index 3c6cd609..7f183077 100644
--- a/orchestra/contrib/settings/templates/admin/settings/reload.html
+++ b/orchestra/contrib/settings/templates/admin/settings/reload.html
@@ -1,4 +1,4 @@
-{% load staticfiles %}
+{% load static %}
diff --git a/orchestra/contrib/systemusers/actions.py b/orchestra/contrib/systemusers/actions.py
index 80743ea4..1916aa47 100644
--- a/orchestra/contrib/systemusers/actions.py
+++ b/orchestra/contrib/systemusers/actions.py
@@ -3,7 +3,7 @@ import os
from django.contrib import messages, admin
from django.core.exceptions import PermissionDenied
from django.template.response import TemplateResponse
-from django.utils.translation import ungettext, ugettext_lazy as _
+from django.utils.translation import ngettext, gettext_lazy as _
from orchestra.contrib.orchestration import Operation, helpers
diff --git a/orchestra/contrib/systemusers/admin.py b/orchestra/contrib/systemusers/admin.py
index 59b4c271..64362957 100644
--- a/orchestra/contrib/systemusers/admin.py
+++ b/orchestra/contrib/systemusers/admin.py
@@ -1,5 +1,5 @@
from django.contrib import admin, messages
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable, enable
diff --git a/orchestra/contrib/systemusers/api.py b/orchestra/contrib/systemusers/api.py
index 044048e4..b803c810 100644
--- a/orchestra/contrib/systemusers/api.py
+++ b/orchestra/contrib/systemusers/api.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import viewsets, exceptions
from orchestra.api import router, SetPasswordApiMixin, LogApiMixin
diff --git a/orchestra/contrib/systemusers/backends.py b/orchestra/contrib/systemusers/backends.py
index 22dde957..fdc38f25 100644
--- a/orchestra/contrib/systemusers/backends.py
+++ b/orchestra/contrib/systemusers/backends.py
@@ -2,7 +2,7 @@ import fnmatch
import os
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
from orchestra.contrib.resources import ServiceMonitor
diff --git a/orchestra/contrib/systemusers/filters.py b/orchestra/contrib/systemusers/filters.py
index 8e619a49..7d1d9728 100644
--- a/orchestra/contrib/systemusers/filters.py
+++ b/orchestra/contrib/systemusers/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class IsMainListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/systemusers/forms.py b/orchestra/contrib/systemusers/forms.py
index eaf1d2f8..f95529bb 100644
--- a/orchestra/contrib/systemusers/forms.py
+++ b/orchestra/contrib/systemusers/forms.py
@@ -3,7 +3,7 @@ import textwrap
from django import forms
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.forms import UserCreationForm, UserChangeForm
diff --git a/orchestra/contrib/systemusers/models.py b/orchestra/contrib/systemusers/models.py
index b270bcad..bd6dc048 100644
--- a/orchestra/contrib/systemusers/models.py
+++ b/orchestra/contrib/systemusers/models.py
@@ -6,7 +6,7 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import F
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import validators
diff --git a/orchestra/contrib/systemusers/serializers.py b/orchestra/contrib/systemusers/serializers.py
index e9cf1257..5083b68e 100644
--- a/orchestra/contrib/systemusers/serializers.py
+++ b/orchestra/contrib/systemusers/serializers.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.api.serializers import SetPasswordHyperlinkedSerializer, RelatedHyperlinkedModelSerializer
diff --git a/orchestra/contrib/systemusers/settings.py b/orchestra/contrib/systemusers/settings.py
index 9023b20d..5e931a02 100644
--- a/orchestra/contrib/systemusers/settings.py
+++ b/orchestra/contrib/systemusers/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
diff --git a/orchestra/contrib/systemusers/validators.py b/orchestra/contrib/systemusers/validators.py
index fbe4e9a0..cafea1c2 100644
--- a/orchestra/contrib/systemusers/validators.py
+++ b/orchestra/contrib/systemusers/validators.py
@@ -1,7 +1,7 @@
import os
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import Operation
diff --git a/orchestra/contrib/tasks/admin.py b/orchestra/contrib/tasks/admin.py
index bd249254..d245a5f6 100644
--- a/orchestra/contrib/tasks/admin.py
+++ b/orchestra/contrib/tasks/admin.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from djcelery.admin import PeriodicTaskAdmin
from orchestra.admin.utils import admin_date
diff --git a/orchestra/contrib/vps/admin.py b/orchestra/contrib/vps/admin.py
index b512fd8b..346ddaf9 100644
--- a/orchestra/contrib/vps/admin.py
+++ b/orchestra/contrib/vps/admin.py
@@ -1,5 +1,5 @@
from django.contrib import admin
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.contrib.accounts.actions import list_accounts
diff --git a/orchestra/contrib/vps/models.py b/orchestra/contrib/vps/models.py
index fe3c62c9..f5b19f7b 100644
--- a/orchestra/contrib/vps/models.py
+++ b/orchestra/contrib/vps/models.py
@@ -1,6 +1,6 @@
from django.contrib.auth.hashers import make_password
from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core.validators import validate_hostname
diff --git a/orchestra/contrib/webapps/admin.py b/orchestra/contrib/webapps/admin.py
index 29247079..d1dc7a18 100644
--- a/orchestra/contrib/webapps/admin.py
+++ b/orchestra/contrib/webapps/admin.py
@@ -1,9 +1,9 @@
from django import forms
from django.contrib import admin
from django.urls import reverse
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext, ugettext_lazy as _
+from django.utils.translation import gettext, gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.utils import admin_link, get_modeladmin
@@ -24,7 +24,7 @@ class WebAppOptionInline(admin.TabularInline):
extra = 1
OPTIONS_HELP_TEXT = {
- op.name: force_text(op.help_text) for op in AppOption.get_plugins()
+ op.name: force_str(op.help_text) for op in AppOption.get_plugins()
}
class Media:
@@ -74,14 +74,15 @@ class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin)
site_url = content.get_absolute_url()
site_link = get_on_site_link(site_url)
website = content.website
- name = "%s on %s %s" % (website.name, content.path, site_link)
+ #name = "%s on %s %s" % (website.name, content.path, site_link)
+ name = "%s on %s" % (website.name, content.path)
link = admin_link(display=name)(website)
websites.append(link)
if not websites:
add_url = reverse('admin:websites_website_add')
add_url += '?account=%s' % webapp.account_id
plus = '+'
- websites.append('%s%s' % (add_url, plus, ugettext("Add website")))
+ websites.append('%s%s' % (add_url, plus, gettext("Add website")))
return '
'.join(websites)
display_websites.short_description = _("web sites")
diff --git a/orchestra/contrib/webapps/backends/moodle.py b/orchestra/contrib/webapps/backends/moodle.py
index b5d85305..5579e8a4 100644
--- a/orchestra/contrib/webapps/backends/moodle.py
+++ b/orchestra/contrib/webapps/backends/moodle.py
@@ -1,7 +1,7 @@
import os
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
diff --git a/orchestra/contrib/webapps/backends/php.py b/orchestra/contrib/webapps/backends/php.py
index 360f3eb1..7478fc41 100644
--- a/orchestra/contrib/webapps/backends/php.py
+++ b/orchestra/contrib/webapps/backends/php.py
@@ -2,8 +2,8 @@ import os
import textwrap
from collections import OrderedDict
-from django.template import Template
-from django.utils.translation import ugettext_lazy as _
+from django.template import Template, Context
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
@@ -245,7 +245,7 @@ class PHPController(WebAppServiceMixin, ServiceController):
php_admin_value[{{ name | safe }}] = {{ value | safe }}{% endfor %}
"""
))
- return fpm_config.render(context)
+ return fpm_config.render(Context(context))
def get_fcgid_wrapper(self, webapp, context):
opt = webapp.type_instance
diff --git a/orchestra/contrib/webapps/backends/python.py b/orchestra/contrib/webapps/backends/python.py
index fa0b9881..63013d5e 100644
--- a/orchestra/contrib/webapps/backends/python.py
+++ b/orchestra/contrib/webapps/backends/python.py
@@ -1,7 +1,7 @@
import os
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
diff --git a/orchestra/contrib/webapps/backends/static.py b/orchestra/contrib/webapps/backends/static.py
index f5173190..f424d505 100644
--- a/orchestra/contrib/webapps/backends/static.py
+++ b/orchestra/contrib/webapps/backends/static.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
diff --git a/orchestra/contrib/webapps/backends/symboliclink.py b/orchestra/contrib/webapps/backends/symboliclink.py
index 1b43f0de..2ba3fac2 100644
--- a/orchestra/contrib/webapps/backends/symboliclink.py
+++ b/orchestra/contrib/webapps/backends/symboliclink.py
@@ -1,6 +1,6 @@
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
diff --git a/orchestra/contrib/webapps/backends/webalizer.py b/orchestra/contrib/webapps/backends/webalizer.py
index d715e983..c9d35560 100644
--- a/orchestra/contrib/webapps/backends/webalizer.py
+++ b/orchestra/contrib/webapps/backends/webalizer.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
diff --git a/orchestra/contrib/webapps/backends/wordpress.py b/orchestra/contrib/webapps/backends/wordpress.py
index cbb1641a..819be388 100644
--- a/orchestra/contrib/webapps/backends/wordpress.py
+++ b/orchestra/contrib/webapps/backends/wordpress.py
@@ -1,7 +1,7 @@
import os
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController, replace
diff --git a/orchestra/contrib/webapps/filters.py b/orchestra/contrib/webapps/filters.py
index a79cd228..794217bf 100644
--- a/orchestra/contrib/webapps/filters.py
+++ b/orchestra/contrib/webapps/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .types import AppType
diff --git a/orchestra/contrib/webapps/models.py b/orchestra/contrib/webapps/models.py
index 42b3a227..21f07979 100644
--- a/orchestra/contrib/webapps/models.py
+++ b/orchestra/contrib/webapps/models.py
@@ -3,7 +3,7 @@ from collections import OrderedDict
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from orchestra.core import validators
diff --git a/orchestra/contrib/webapps/options.py b/orchestra/contrib/webapps/options.py
index dad0ec87..66a9a373 100644
--- a/orchestra/contrib/webapps/options.py
+++ b/orchestra/contrib/webapps/options.py
@@ -3,7 +3,7 @@ import re
from functools import lru_cache
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra import plugins
from orchestra.utils.python import import_class
@@ -204,6 +204,10 @@ class PHPIncludePath(PHPAppOption):
verbose_name = _("Include path")
regex = r'^[^ ]+$'
+class PHPOpenBasedir(PHPAppOption):
+ name = 'open_basedir'
+ verbose_name = _("Open basedir")
+ regex = r'^[^ ]+$'
class PHPMagicQuotesGPC(PHPAppOption):
name = 'magic_quotes_gpc'
diff --git a/orchestra/contrib/webapps/settings.py b/orchestra/contrib/webapps/settings.py
index 625de96f..19471c59 100644
--- a/orchestra/contrib/webapps/settings.py
+++ b/orchestra/contrib/webapps/settings.py
@@ -235,6 +235,7 @@ WEBAPPS_ENABLED_OPTIONS = Setting('WEBAPPS_ENABLED_OPTIONS', (
'orchestra.contrib.webapps.options.PHPDisplayErrors',
'orchestra.contrib.webapps.options.PHPExtension',
'orchestra.contrib.webapps.options.PHPIncludePath',
+ 'orchestra.contrib.webapps.options.PHPOpenBasedir',
'orchestra.contrib.webapps.options.PHPMagicQuotesGPC',
'orchestra.contrib.webapps.options.PHPMagicQuotesRuntime',
'orchestra.contrib.webapps.options.PHPMaginQuotesSybase',
diff --git a/orchestra/contrib/webapps/types/__init__.py b/orchestra/contrib/webapps/types/__init__.py
index 33020d32..eb1b7d18 100644
--- a/orchestra/contrib/webapps/types/__init__.py
+++ b/orchestra/contrib/webapps/types/__init__.py
@@ -3,7 +3,7 @@ import os
from functools import lru_cache
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra import plugins
from orchestra.plugins.forms import PluginDataForm
diff --git a/orchestra/contrib/webapps/types/cms.py b/orchestra/contrib/webapps/types/cms.py
index 0343ce15..03524d74 100644
--- a/orchestra/contrib/webapps/types/cms.py
+++ b/orchestra/contrib/webapps/types/cms.py
@@ -2,7 +2,7 @@ from django import forms
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.contrib.databases.models import Database, DatabaseUser
diff --git a/orchestra/contrib/webapps/types/misc.py b/orchestra/contrib/webapps/types/misc.py
index f3837fd6..1619bbf3 100644
--- a/orchestra/contrib/webapps/types/misc.py
+++ b/orchestra/contrib/webapps/types/misc.py
@@ -1,7 +1,7 @@
import os
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from ..options import AppOption
diff --git a/orchestra/contrib/webapps/types/moodle.py b/orchestra/contrib/webapps/types/moodle.py
index 54921dd6..aef8bbce 100644
--- a/orchestra/contrib/webapps/types/moodle.py
+++ b/orchestra/contrib/webapps/types/moodle.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .cms import CMSApp
diff --git a/orchestra/contrib/webapps/types/php.py b/orchestra/contrib/webapps/types/php.py
index 8c1e6522..accdb0a8 100644
--- a/orchestra/contrib/webapps/types/php.py
+++ b/orchestra/contrib/webapps/types/php.py
@@ -2,7 +2,7 @@ import os
from collections import OrderedDict
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.plugins.forms import PluginDataForm
diff --git a/orchestra/contrib/webapps/types/python.py b/orchestra/contrib/webapps/types/python.py
index ec9984e4..22ff0297 100644
--- a/orchestra/contrib/webapps/types/python.py
+++ b/orchestra/contrib/webapps/types/python.py
@@ -1,7 +1,7 @@
import re
from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from orchestra.plugins.forms import PluginDataForm
diff --git a/orchestra/contrib/webapps/types/wordpress.py b/orchestra/contrib/webapps/types/wordpress.py
index 0d02ff8f..926f7acc 100644
--- a/orchestra/contrib/webapps/types/wordpress.py
+++ b/orchestra/contrib/webapps/types/wordpress.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .cms import CMSApp
diff --git a/orchestra/contrib/websites/admin.py b/orchestra/contrib/websites/admin.py
index a6a68c55..581796d6 100644
--- a/orchestra/contrib/websites/admin.py
+++ b/orchestra/contrib/websites/admin.py
@@ -2,10 +2,10 @@ from django import forms
from django.contrib import admin
from django.urls import resolve
from django.db.models import Q
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.actions import disable, enable
@@ -28,7 +28,7 @@ class WebsiteDirectiveInline(admin.TabularInline):
extra = 1
DIRECTIVES_HELP_TEXT = {
- op.name: force_text(op.help_text) for op in SiteDirective.get_plugins()
+ op.name: force_str(op.help_text) for op in SiteDirective.get_plugins()
}
def formfield_for_dbfield(self, db_field, **kwargs):
@@ -121,9 +121,8 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
Q(websites__protocol=Website.HTTP) & Q(websites__protocol=Website.HTTPS)
)
)
- args = resolve(kwargs['request'].path).args
- if args:
- object_id = args[0]
+ object_id = kwargs['request'].resolver_match.kwargs.get('object_id')
+ if object_id:
qset = Q(qset & ~Q(websites__pk=object_id))
formfield.queryset = formfield.queryset.exclude(qset)
return formfield
diff --git a/orchestra/contrib/websites/backends/apache.py b/orchestra/contrib/websites/backends/apache.py
index ad664eea..40aafdee 100644
--- a/orchestra/contrib/websites/backends/apache.py
+++ b/orchestra/contrib/websites/backends/apache.py
@@ -2,8 +2,8 @@ import os
import re
import textwrap
-from django.template import Template
-from django.utils.translation import ugettext_lazy as _
+from django.template import Template, Context
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.resources import ServiceMonitor
@@ -78,7 +78,7 @@ class Apache2Controller(ServiceController):
{{ line | safe }}{% endfor %}
""")
- ).render(context)
+ ).render(Context(context))
def render_redirect_https(self, context):
context['port'] = self.HTTP_PORT
@@ -96,7 +96,7 @@ class Apache2Controller(ServiceController):
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
""")
- ).render(context)
+ ).render(Context(context))
def save(self, site):
context = self.get_context(site)
diff --git a/orchestra/contrib/websites/backends/webalizer.py b/orchestra/contrib/websites/backends/webalizer.py
index 63401cec..093aa6bd 100644
--- a/orchestra/contrib/websites/backends/webalizer.py
+++ b/orchestra/contrib/websites/backends/webalizer.py
@@ -1,7 +1,7 @@
import os
import textwrap
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.orchestration import ServiceController
diff --git a/orchestra/contrib/websites/directives.py b/orchestra/contrib/websites/directives.py
index 190f1adc..6192d164 100644
--- a/orchestra/contrib/websites/directives.py
+++ b/orchestra/contrib/websites/directives.py
@@ -3,7 +3,7 @@ from collections import defaultdict
from functools import lru_cache
from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra import plugins
from orchestra.utils.python import import_class
@@ -83,7 +83,7 @@ class SiteDirective(plugins.Plugin, metaclass=plugins.PluginMount):
if value is not None:
if self.unique_value and value in values.get(self.name, []):
errors['value'].append(ValidationError(
- _("This value is already used by other %s.") % force_text(self.get_verbose_name())
+ _("This value is already used by other %s.") % force_str(self.get_verbose_name())
))
values[self.name].append(value)
if errors:
diff --git a/orchestra/contrib/websites/filters.py b/orchestra/contrib/websites/filters.py
index 5fb19f44..11016195 100644
--- a/orchestra/contrib/websites/filters.py
+++ b/orchestra/contrib/websites/filters.py
@@ -1,5 +1,5 @@
from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
class HasWebAppsListFilter(SimpleListFilter):
diff --git a/orchestra/contrib/websites/models.py b/orchestra/contrib/websites/models.py
index f71d1a1f..b9f00bbd 100644
--- a/orchestra/contrib/websites/models.py
+++ b/orchestra/contrib/websites/models.py
@@ -3,7 +3,7 @@ from collections import OrderedDict
from django.db import models
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.core import validators
from orchestra.utils.functional import cached
diff --git a/orchestra/contrib/websites/settings.py b/orchestra/contrib/websites/settings.py
index 362d4ea4..147828f1 100644
--- a/orchestra/contrib/websites/settings.py
+++ b/orchestra/contrib/websites/settings.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
from orchestra.core.validators import validate_ip_address
diff --git a/orchestra/contrib/websites/validators.py b/orchestra/contrib/websites/validators.py
index 144cc52a..348a1cf0 100644
--- a/orchestra/contrib/websites/validators.py
+++ b/orchestra/contrib/websites/validators.py
@@ -1,6 +1,6 @@
from django.core.exceptions import ValidationError
from django.db.models import Q
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from .models import Website
diff --git a/orchestra/core/validators.py b/orchestra/core/validators.py
index ef4a2730..f6e1fccd 100644
--- a/orchestra/core/validators.py
+++ b/orchestra/core/validators.py
@@ -6,7 +6,7 @@ import phonenumbers
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from ..utils.python import import_class
diff --git a/orchestra/forms/options.py b/orchestra/forms/options.py
index 4b3fbf40..5dfda313 100644
--- a/orchestra/forms/options.py
+++ b/orchestra/forms/options.py
@@ -1,6 +1,6 @@
from django import forms
from django.contrib.auth import forms as auth_forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.utils.python import random_ascii
diff --git a/orchestra/forms/widgets.py b/orchestra/forms/widgets.py
index 74a0fd29..84e0f1ef 100644
--- a/orchestra/forms/widgets.py
+++ b/orchestra/forms/widgets.py
@@ -4,7 +4,7 @@ import textwrap
from django import forms
from django.utils.safestring import mark_safe
-from django.contrib.admin.templatetags.admin_static import static
+from django.templatetags.static import static
class SpanWidget(forms.Widget):
diff --git a/orchestra/models/fields.py b/orchestra/models/fields.py
index 81ab5796..12b31007 100644
--- a/orchestra/models/fields.py
+++ b/orchestra/models/fields.py
@@ -35,7 +35,7 @@ class MultiSelectField(models.CharField):
return value
return []
- def from_db_value(self, value, expression, connection, context):
+ def from_db_value(self, value, expression, connection):
if value:
if isinstance(value, str):
return value.split(',')
diff --git a/orchestra/plugins/admin.py b/orchestra/plugins/admin.py
index 9f245876..4183ced8 100644
--- a/orchestra/plugins/admin.py
+++ b/orchestra/plugins/admin.py
@@ -1,9 +1,9 @@
import re
-from django.conf.urls import url
+from django.urls import re_path as url
from django.contrib.admin.utils import unquote
from django.shortcuts import render, redirect
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.admin.utils import wrap_admin_view
@@ -46,7 +46,7 @@ class SelectPluginAdminMixin(object):
opts = self.model._meta
info = opts.app_label, opts.model_name
select_urls = [
- url("select-plugin/$",
+ url("add/select-plugin/$",
wrap_admin_view(self, self.select_plugin_view),
name='%s_%s_select_plugin' % info),
]
diff --git a/orchestra/plugins/forms.py b/orchestra/plugins/forms.py
index 0394f742..d788f369 100644
--- a/orchestra/plugins/forms.py
+++ b/orchestra/plugins/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from orchestra.admin.utils import admin_link
from orchestra.forms.widgets import SpanWidget
@@ -10,7 +10,7 @@ class PluginForm(forms.ModelForm):
super().__init__(*args, **kwargs)
if self.plugin_field in self.fields:
value = self.plugin.get_name()
- display = '%s change' % force_text(self.plugin.verbose_name)
+ display = '%s change' % force_str(self.plugin.verbose_name)
self.fields[self.plugin_field].widget = SpanWidget(original=value, display=display)
help_text = self.fields[self.plugin_field].help_text
self.fields[self.plugin_field].help_text = getattr(self.plugin, 'help_text', help_text)
diff --git a/orchestra/plugins/options.py b/orchestra/plugins/options.py
index 581c94de..c79d94c3 100644
--- a/orchestra/plugins/options.py
+++ b/orchestra/plugins/options.py
@@ -38,7 +38,7 @@ class Plugin(object):
@classmethod
def get_verbose_name(cls):
- # don't evaluate p.verbose_name ugettext_lazy
+ # don't evaluate p.verbose_name gettext_lazy
verbose = getattr(cls.verbose_name, '_proxy____args', [cls.verbose_name])
if verbose[0]:
return cls.verbose_name
diff --git a/orchestra/settings.py b/orchestra/settings.py
index 9dd45566..86c39ca8 100644
--- a/orchestra/settings.py
+++ b/orchestra/settings.py
@@ -1,5 +1,5 @@
from django.core.validators import validate_email
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.contrib.settings import Setting
diff --git a/orchestra/templates/admin/base.html b/orchestra/templates/admin/base.html
index 076a3973..475cf750 100644
--- a/orchestra/templates/admin/base.html
+++ b/orchestra/templates/admin/base.html
@@ -1,4 +1,4 @@
-{% load theming_tags staticfiles %}
+{% load theming_tags static %}
diff --git a/orchestra/templates/admin/login.html b/orchestra/templates/admin/login.html
index 1131e658..598251bd 100644
--- a/orchestra/templates/admin/login.html
+++ b/orchestra/templates/admin/login.html
@@ -1,5 +1,5 @@
{% extends "admin/base_site.html" %}
-{% load i18n admin_static utils %}
+{% load i18n static utils %}
{% block extrastyle %}
{{ block.super }}
diff --git a/orchestra/templates/admin/orchestra/menu.html b/orchestra/templates/admin/orchestra/menu.html
index 8cf8effa..c6d0960c 100644
--- a/orchestra/templates/admin/orchestra/menu.html
+++ b/orchestra/templates/admin/orchestra/menu.html
@@ -1,4 +1,4 @@
-{% load i18n admin_tools_menu_tags staticfiles %}
+{% load i18n admin_tools_menu_tags static %}
{% if menu.children %}
diff --git a/orchestra/templates/admin/plugins/select_plugin.html b/orchestra/templates/admin/plugins/select_plugin.html
index e425b75b..1eaba4fc 100644
--- a/orchestra/templates/admin/plugins/select_plugin.html
+++ b/orchestra/templates/admin/plugins/select_plugin.html
@@ -1,5 +1,5 @@
{% extends "admin/orchestra/generic_confirmation.html" %}
-{% load i18n l10n staticfiles admin_urls admin_tools_dashboard_tags %}
+{% load i18n l10n static admin_urls admin_tools_dashboard_tags %}
{% block extrastyle %}
{{ block.super }}
diff --git a/orchestra/templates/rest_framework/api.html b/orchestra/templates/rest_framework/api.html
index f070bc05..fadbb653 100644
--- a/orchestra/templates/rest_framework/api.html
+++ b/orchestra/templates/rest_framework/api.html
@@ -1,5 +1,5 @@
{% extends "rest_framework/base.html" %}
-{% load rest_framework utils staticfiles %}
+{% load rest_framework utils static %}
{% block meta %}
{{ block.super }}
diff --git a/orchestra/utils/html.py b/orchestra/utils/html.py
index c8741542..5719a6fa 100644
--- a/orchestra/utils/html.py
+++ b/orchestra/utils/html.py
@@ -2,7 +2,7 @@ import textwrap
from django.templatetags.static import static
from django.utils.html import format_html
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from orchestra.utils.sys import run
@@ -19,7 +19,8 @@ def html_to_pdf(html, pagination=False):
}
cmd = textwrap.dedent("""\
PATH=$PATH:/usr/local/bin/
- xvfb-run -a -s "-screen 0 2480x3508x16" wkhtmltopdf -q \\
+ xvfb-run -a -s "-screen 0 2480x3508x16" wkhtmltopdf -q \\
+ --enable-local-file-access \\
--use-xserver \\
%(pagination)s \\
--margin-bottom 22 \\
diff --git a/orchestra/utils/humanize.py b/orchestra/utils/humanize.py
index d905b883..4cee3466 100644
--- a/orchestra/utils/humanize.py
+++ b/orchestra/utils/humanize.py
@@ -1,13 +1,13 @@
from datetime import datetime
from django.utils import timezone
-from django.utils.translation import ungettext, ugettext as _
+from django.utils.translation import ngettext, gettext as _
def verbose_time(n, units, ago='ago'):
if n >= 5:
return _("{n} {units} {ago}").format(n=int(n), units=units, ago=ago)
- return ungettext(
+ return ngettext(
_("{n:.1f} {s_units} {ago}"),
_("{n:.1f} {units} {ago}"), n
).format(n=n, units=units, s_units=units[:-1], ago=ago)
@@ -22,7 +22,7 @@ OLDER_CHUNKS = (
def _un(singular__plural, n=None):
singular, plural = singular__plural
- return ungettext(singular, plural, n)
+ return ngettext(singular, plural, n)
def naturaldatetime(date, show_seconds=False):
diff --git a/orchestra/utils/sys.py b/orchestra/utils/sys.py
index fc732343..bfb82674 100644
--- a/orchestra/utils/sys.py
+++ b/orchestra/utils/sys.py
@@ -111,7 +111,8 @@ def runiterator(command, display=False, stdin=b''):
if state.exit_code != None:
p.stdout.close()
p.stderr.close()
- raise StopIteration
+ return
+ # raise StopIteration
def join(iterator, display=False, silent=False, valid_codes=(0,)):
@@ -165,6 +166,11 @@ def sshrun(addr, command, *args, executable='bash', persist=False, options=None,
'stricthostkeychecking': 'no',
'BatchMode': 'yes',
'EscapeChar': 'none',
+ # Send keep alives to prevent stale or broken connections when no data is being sent
+ # default tcp timeout: 900 seconds
+ 'ServerAliveInterval': '300',
+ # Max number of consecutive keep alives without response
+ 'ServerAliveCountMax': '2',
}
if persist:
base_options.update({
diff --git a/requirements.txt b/requirements.txt
index 13ed05bb..14d5ce5e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -18,6 +18,6 @@ requests
phonenumbers==8.12.27
django-countries
django-localflavor==3.1
-amqp<2.0,>=1.4.9
+amqp
anyjson
pytz