mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-19 05:58:34 +02:00
@@ -25,7 +25,6 @@ def viewsettings(request, tplname='core/settings_header.html'):
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def viewparameters(request, tplname='core/parameters.html'):
|
||||
return render_to_json_response({
|
||||
"status": "ok",
|
||||
"left_selection": "parameters",
|
||||
"content": _render_to_string(request, tplname, {
|
||||
"forms": parameters.get_admin_forms
|
||||
|
||||
@@ -37,6 +37,9 @@ admin_events = [
|
||||
"ExtraAccountForm",
|
||||
"CheckExtraAccountForm",
|
||||
"FillAccountInstances",
|
||||
|
||||
"ExtraDomainImportHelp",
|
||||
"ImportObject"
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from itertools import chain
|
||||
from django.db.models import Q
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import parameters, events
|
||||
from modoboa.lib.exceptions import PermDeniedException
|
||||
|
||||
@@ -134,5 +134,7 @@ class Domain(AdminObject):
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
csvwriter.writerow(["domain", self.name, self.quota, self.enabled])
|
||||
for dalias in self.domainalias_set.all():
|
||||
dalias.to_csv(csvwriter)
|
||||
|
||||
reversion.register(Domain)
|
||||
|
||||
@@ -125,7 +125,7 @@ Admin.prototype = {
|
||||
$("#import_status").css("display", "none");
|
||||
if (status == "ok") {
|
||||
$("#modalbox").modal('hide');
|
||||
this.reload_listing({respmsg: msg});
|
||||
this.reload_listing(msg);
|
||||
} else {
|
||||
$("#import_result").addClass("alert alert-error");
|
||||
$("#import_result").html(msg);
|
||||
|
||||
@@ -70,7 +70,7 @@ class AccountTestCase(ModoTestCase):
|
||||
def test_set_nul_quota_as_domainadmin(self):
|
||||
self.clt.logout()
|
||||
self.assertTrue(self.clt.login(username="admin@test.com", password="toto"))
|
||||
self._set_quota("user@test.com", 0, 424)
|
||||
self._set_quota("user@test.com", 0, 400)
|
||||
self.clt.logout()
|
||||
self.assertTrue(self.clt.login(username="admin@test2.com", password="toto"))
|
||||
self._set_quota("user@test2.com", 0)
|
||||
|
||||
@@ -40,6 +40,7 @@ def _domains(request):
|
||||
for flt in ['domfilter', 'searchquery']
|
||||
+ events.raiseQueryEvent('ExtraDomainFilters')
|
||||
)
|
||||
request.session['domains_filters'] = filters
|
||||
domainlist = get_domains(
|
||||
request.user, **filters
|
||||
)
|
||||
|
||||
@@ -8,8 +8,7 @@ from django.utils.translation import ugettext as _
|
||||
from django.contrib.auth.decorators import (
|
||||
login_required, permission_required, user_passes_test
|
||||
)
|
||||
from modoboa.extensions.admin.lib import get_identities
|
||||
from modoboa.extensions.admin.models import Domain
|
||||
from modoboa.extensions.admin.lib import get_domains, get_identities
|
||||
from modoboa.extensions.admin.forms import (
|
||||
ExportIdentitiesForm, ExportDomainsForm
|
||||
)
|
||||
@@ -73,10 +72,9 @@ def export_domains(request):
|
||||
form.is_valid()
|
||||
fp = cStringIO.StringIO()
|
||||
csvwriter = csv.writer(fp, delimiter=form.cleaned_data["sepchar"])
|
||||
for dom in Domain.objects.get_for_admin(request.user):
|
||||
for dom in get_domains(request.user,
|
||||
**request.session['domains_filters']):
|
||||
dom.to_csv(csvwriter)
|
||||
for da in dom.domainalias_set.all():
|
||||
da.to_csv(csvwriter)
|
||||
content = fp.getvalue()
|
||||
fp.close()
|
||||
return _export(content, form.cleaned_data["filename"])
|
||||
|
||||
@@ -6,6 +6,7 @@ from django.db import transaction, IntegrityError
|
||||
from django.contrib.auth.decorators import (
|
||||
login_required, permission_required, user_passes_test
|
||||
)
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib.exceptions import ModoboaException, Conflict
|
||||
from modoboa.core.models import User
|
||||
from modoboa.extensions.admin.models import (
|
||||
@@ -39,10 +40,11 @@ def import_domains(request):
|
||||
<ul>
|
||||
<li><em>domain; name; quota; enabled</em></li>
|
||||
<li><em>domainalias; name; targeted domain; enabled</em></li>
|
||||
%s
|
||||
</ul>
|
||||
<p>The first element of each line is mandatory and must be equal to one of the previous values.</p>
|
||||
<p>You can use a different character as separator.</p>
|
||||
""")
|
||||
""" % ''.join([unicode(hlp) for hlp in events.raiseQueryEvent('ExtraDomainImportHelp')]))
|
||||
|
||||
ctx = dict(
|
||||
title=_("Import domains"),
|
||||
@@ -100,8 +102,8 @@ def importdata(request, formclass=ImportDataForm):
|
||||
try:
|
||||
reader = csv.reader(request.FILES['sourcefile'],
|
||||
delimiter=form.cleaned_data['sepchar'])
|
||||
except csv.Error, e:
|
||||
error = str(e)
|
||||
except csv.Error as inst:
|
||||
error = str(inst)
|
||||
|
||||
if error is None:
|
||||
try:
|
||||
@@ -112,13 +114,21 @@ def importdata(request, formclass=ImportDataForm):
|
||||
try:
|
||||
fct = globals()["import_%s" % row[0].strip()]
|
||||
except KeyError:
|
||||
continue
|
||||
fct = events.raiseQueryEvent(
|
||||
'ImportObject', row[0].strip()
|
||||
)
|
||||
if not fct:
|
||||
continue
|
||||
fct = fct[0]
|
||||
try:
|
||||
fct(request.user, row, form.cleaned_data)
|
||||
except IntegrityError, e:
|
||||
if form.cleaned_data["continue_if_exists"]:
|
||||
continue
|
||||
raise Conflict(_("Object already exists: %s" % row))
|
||||
raise Conflict(
|
||||
_("Object already exists: %s"
|
||||
% form.cleaned_data['sepchar'].join(row[:2]))
|
||||
)
|
||||
cpt += 1
|
||||
msg = _("%d objects imported successfully" % cpt)
|
||||
return render(request, "admin/import_done.html", {
|
||||
|
||||
@@ -201,3 +201,22 @@ def extra_parameters(app, level):
|
||||
widget=forms.widgets.TextInput(attrs={"class": "span1"})
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@events.observe('ExtraDomainImportHelp')
|
||||
def extra_domain_import_help():
|
||||
return [ugettext_lazy("""
|
||||
<li><em>relaydomain; name; target host; service; enabled; verify recipients</em></li>
|
||||
<li><em>relaydomainalias; name; target; enabled</em></li>
|
||||
""")]
|
||||
|
||||
|
||||
@events.observe('ImportObject')
|
||||
def get_import_func(objtype):
|
||||
from .lib import import_relaydomain, import_relaydomainalias
|
||||
|
||||
if objtype == 'relaydomain':
|
||||
return [import_relaydomain]
|
||||
if objtype == 'relaydomainalias':
|
||||
return [import_relaydomainalias]
|
||||
return []
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
from django.db import transaction
|
||||
from .models import RelayDomain, RelayDomainAlias
|
||||
|
||||
|
||||
@transaction.commit_on_success
|
||||
def import_relaydomain(user, row, formopts):
|
||||
"""Specific code for relay domains import"""
|
||||
RelayDomain().from_csv(user, row)
|
||||
|
||||
|
||||
@transaction.commit_on_success
|
||||
def import_relaydomainalias(user, row, formopts):
|
||||
"""Specific code for relay domain aliases import"""
|
||||
RelayDomainAlias().from_csv(user, row)
|
||||
@@ -4,8 +4,8 @@ from django.db.models.manager import Manager
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from modoboa.core.models import ObjectAccess
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.lib.permissions import ungrant_access_to_object
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib.exceptions import BadRequest, NotFound
|
||||
from modoboa.extensions.admin.models import AdminObject
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ class ServiceManager(Manager):
|
||||
|
||||
|
||||
class Service(models.Model):
|
||||
"""Postfix service.
|
||||
"""
|
||||
name = models.CharField(
|
||||
ugettext_lazy('name'), max_length=100, unique=True,
|
||||
help_text=ugettext_lazy('The service name')
|
||||
@@ -106,6 +108,33 @@ class RelayDomain(AdminObject):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
"""Export this relay domain to CSV.
|
||||
|
||||
:param csvwriter:
|
||||
"""
|
||||
csvwriter.writerow(
|
||||
["relaydomain", self.name, self.target_host,
|
||||
self.service.name, self.enabled, self.verify_recipients]
|
||||
)
|
||||
for rdalias in self.relaydomainalias_set.all():
|
||||
rdalias.to_csv(csvwriter)
|
||||
|
||||
def from_csv(self, user, row):
|
||||
"""Import a relay domain from CSV.
|
||||
|
||||
:param user: user importing the relay domain
|
||||
:param str row: relay domain definition
|
||||
"""
|
||||
if len(row) != 6:
|
||||
raise BadRequest(_("Invalid line"))
|
||||
self.name = row[1].strip()
|
||||
self.target_host = row[2].strip()
|
||||
self.service, created = Service.objects.get_or_create(name=row[3].strip())
|
||||
self.enabled = (row[4].strip() == 'True')
|
||||
self.verify_recipients = (row[5].strip() == 'True')
|
||||
self.save(creator=user)
|
||||
|
||||
reversion.register(RelayDomain)
|
||||
|
||||
|
||||
@@ -126,4 +155,29 @@ class RelayDomainAlias(AdminObject):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
"""Export this relay domain alias to CSV.
|
||||
|
||||
:param csvwriter:
|
||||
"""
|
||||
csvwriter.writerow(
|
||||
['relaydomainalias', self.name, self.target.name, self.enabled]
|
||||
)
|
||||
|
||||
def from_csv(self, user, row):
|
||||
"""Import a relay domain alias from CSV.
|
||||
|
||||
:param user: user importing the relay domain alias
|
||||
:param str row: relay domain alias definition
|
||||
"""
|
||||
if len(row) != 4:
|
||||
raise BadRequest(_("Invalid line"))
|
||||
self.name = row[1].strip()
|
||||
try:
|
||||
self.target = RelayDomain.objects.get(name=row[2].strip())
|
||||
except RelayDomain.DoesNotExist:
|
||||
raise NotFound(_("Relay domain %s does not exist" % row[2].strip()))
|
||||
self.enabled = (row[3].strip() == 'True')
|
||||
self.save(creator=user)
|
||||
|
||||
reversion.register(RelayDomainAlias)
|
||||
|
||||
Reference in New Issue
Block a user