mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
@@ -1,53 +0,0 @@
|
||||
import os.path
|
||||
import sys
|
||||
import csv
|
||||
from progressbar import ProgressBar, Percentage, Bar, ETA
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib.exceptions import Conflict
|
||||
|
||||
from ... import lib
|
||||
|
||||
|
||||
def import_csv(filename, options):
|
||||
"""Import objects from a CSV file."""
|
||||
superadmin = User.objects.filter(is_superuser=True).first()
|
||||
if not os.path.exists(filename):
|
||||
print('File not found')
|
||||
sys.exit(1)
|
||||
|
||||
num_lines = sum(1 for line in open(filename))
|
||||
pbar = ProgressBar(
|
||||
widgets=[Percentage(), Bar(), ETA()], maxval=num_lines
|
||||
).start()
|
||||
with open(filename, 'r') as f:
|
||||
reader = csv.reader(f, delimiter=';')
|
||||
i = 0
|
||||
for row in reader:
|
||||
i += 1
|
||||
pbar.update(i)
|
||||
if not row:
|
||||
continue
|
||||
|
||||
try:
|
||||
fct = getattr(lib, "import_%s" % row[0].strip())
|
||||
except AttributeError:
|
||||
fct = events.raiseQueryEvent(
|
||||
'ImportObject', row[0].strip())
|
||||
if not fct:
|
||||
continue
|
||||
fct = fct[0]
|
||||
|
||||
try:
|
||||
fct(superadmin, row, options)
|
||||
except Conflict:
|
||||
if options['continue_if_exists']:
|
||||
continue
|
||||
|
||||
raise Conflict(
|
||||
"Object already exists: %s"
|
||||
% options['sepchar'].join(row[:2])
|
||||
)
|
||||
|
||||
pbar.finish()
|
||||
@@ -1,24 +0,0 @@
|
||||
import sys
|
||||
import csv
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from ...models import Domain
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Export domains and domain aliases to a csv'
|
||||
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option(
|
||||
'--sepchar', action='store_true', dest='sepchar', default=';'
|
||||
),
|
||||
)
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
exts_pool.load_all()
|
||||
csvwriter = csv.writer(sys.stdout, delimiter=kwargs['sepchar'])
|
||||
for dom in Domain.objects.all():
|
||||
dom.to_csv(csvwriter)
|
||||
@@ -1,29 +0,0 @@
|
||||
import sys
|
||||
import csv
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from ...models import Alias
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Export identities (mailbox and aliases) to a csv'
|
||||
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option(
|
||||
'--sepchar', action='store_true', dest='sepchar', default=';'
|
||||
),
|
||||
)
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
exts_pool.load_all()
|
||||
|
||||
csvwriter = csv.writer(sys.stdout, delimiter=kwargs['sepchar'])
|
||||
for u in User.objects.all():
|
||||
u.to_csv(csvwriter)
|
||||
|
||||
for a in Alias.objects.prefetch_related('aliasrecipient_set'):
|
||||
a.to_csv(csvwriter)
|
||||
@@ -1,27 +0,0 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from modoboa.core.extensions import exts_pool
|
||||
|
||||
from ._import import import_csv
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
args = 'csvfile'
|
||||
help = 'Import domains and domain aliases from a csv file'
|
||||
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option(
|
||||
'--sepchar', action='store_true', dest='sepchar', default=';'
|
||||
),
|
||||
make_option(
|
||||
'--continue-if-exists', action='store_true',
|
||||
dest='continue_if_exists', default=True
|
||||
)
|
||||
)
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
exts_pool.load_all()
|
||||
for filename in args:
|
||||
import_csv(filename, kwargs)
|
||||
@@ -1,30 +0,0 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from modoboa.core.extensions import exts_pool
|
||||
|
||||
from ._import import import_csv
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
args = 'csvfile'
|
||||
help = 'Import identities from a csv file'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
"""Add extra arguments to command."""
|
||||
parser.add_argument(
|
||||
"--sepchar", type=str, default=";",
|
||||
help="Separator used in file.")
|
||||
parser.add_argument(
|
||||
"--continue-if-exists", action="store_true",
|
||||
dest='continue_if_exists', default=True,
|
||||
help="Continue even if an entry already exists.")
|
||||
parser.add_argument(
|
||||
"--crypt-password", action="store_true", dest="crypt_password",
|
||||
default=False, help="Encrypt provided passwords.")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
exts_pool.load_all()
|
||||
for filename in args:
|
||||
import_csv(filename, options)
|
||||
@@ -0,0 +1,20 @@
|
||||
"""Modoboa main management command."""
|
||||
|
||||
from subcommand.base import SubcommandCommand
|
||||
|
||||
from .subcommands._export import ExportCommand
|
||||
from .subcommands._import import ImportCommand
|
||||
|
||||
|
||||
class Command(SubcommandCommand):
|
||||
"""Top management command for modoboa.
|
||||
|
||||
$ python manage.py modo
|
||||
"""
|
||||
|
||||
help = "Modoboa top management command."
|
||||
|
||||
subcommands = {
|
||||
"export": ExportCommand,
|
||||
"import": ImportCommand,
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
"""Django management command to export admin objects."""
|
||||
|
||||
import csv
|
||||
import sys
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from .... import models
|
||||
|
||||
|
||||
class ExportCommand(BaseCommand):
|
||||
"""Command class."""
|
||||
|
||||
help = "Export domains or identities using CSV format"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
"""Add arguments to command."""
|
||||
parser.add_argument(
|
||||
"--sepchar", type=str, dest="sepchar", default=";",
|
||||
help="Separator used in generated file."
|
||||
)
|
||||
parser.add_argument(
|
||||
"objtype", type=str, choices=["domains", "identities"],
|
||||
help="The type of object to export (domains or identities)")
|
||||
|
||||
def export_domains(self):
|
||||
"""Export all domains."""
|
||||
for dom in models.Domain.objects.all():
|
||||
dom.to_csv(self.csvwriter)
|
||||
|
||||
def export_identities(self):
|
||||
"""Export all identities."""
|
||||
for u in User.objects.all():
|
||||
u.to_csv(self.csvwriter)
|
||||
dumped_aliases = []
|
||||
qset = (
|
||||
models.AliasRecipient.objects.filter(r_alias__isnull=False)
|
||||
.distinct("r_alias")
|
||||
.select_related("r_alias")
|
||||
.prefetch_related("r_alias__aliasrecipient_set")
|
||||
)
|
||||
for alr in qset:
|
||||
alr.r_alias.to_csv(self.csvwriter)
|
||||
dumped_aliases += [alr.r_alias.pk]
|
||||
qset = (
|
||||
models.Alias.objects.exclude(pk__in=dumped_aliases)
|
||||
.prefetch_related('aliasrecipient_set')
|
||||
)
|
||||
for alias in qset:
|
||||
alias.to_csv(self.csvwriter)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
exts_pool.load_all()
|
||||
self.csvwriter = csv.writer(sys.stdout, delimiter=options['sepchar'])
|
||||
getattr(self, "export_{}".format(options["objtype"]))()
|
||||
@@ -0,0 +1,84 @@
|
||||
"""Django management command to import admin objects."""
|
||||
|
||||
import csv
|
||||
import os
|
||||
|
||||
import progressbar
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from modoboa.core import models as core_models
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib.exceptions import Conflict
|
||||
|
||||
from .... import lib
|
||||
|
||||
|
||||
class ImportCommand(BaseCommand):
|
||||
"""Command class."""
|
||||
|
||||
args = "csvfile"
|
||||
help = "Import identities from a csv file"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
"""Add extra arguments to command."""
|
||||
parser.add_argument(
|
||||
"--sepchar", type=str, default=";",
|
||||
help="Separator used in file.")
|
||||
parser.add_argument(
|
||||
"--continue-if-exists", action="store_true",
|
||||
dest='continue_if_exists', default=False,
|
||||
help="Continue even if an entry already exists.")
|
||||
parser.add_argument(
|
||||
"--crypt-password", action="store_true",
|
||||
default=False, help="Encrypt provided passwords.")
|
||||
parser.add_argument(
|
||||
"files", type=str, nargs="+", help="CSV files to import.")
|
||||
|
||||
def _import(self, filename, options):
|
||||
"""Import domains or identities."""
|
||||
superadmin = (
|
||||
core_models.User.objects.filter(is_superuser=True).first()
|
||||
)
|
||||
if not os.path.exists(filename):
|
||||
raise CommandError("File not found")
|
||||
|
||||
num_lines = sum(1 for line in open(filename) if line)
|
||||
pbar = progressbar.ProgressBar(
|
||||
widgets=[
|
||||
progressbar.Percentage(), progressbar.Bar(), progressbar.ETA()
|
||||
], maxval=num_lines
|
||||
).start()
|
||||
with open(filename) as f:
|
||||
reader = csv.reader(f, delimiter=options["sepchar"])
|
||||
i = 0
|
||||
for row in reader:
|
||||
if not row:
|
||||
continue
|
||||
try:
|
||||
fct = getattr(lib, "import_%s" % row[0].strip())
|
||||
except AttributeError:
|
||||
fct = events.raiseQueryEvent(
|
||||
"ImportObject", row[0].strip())
|
||||
if not fct:
|
||||
continue
|
||||
fct = fct[0]
|
||||
try:
|
||||
fct(superadmin, row, options)
|
||||
except Conflict:
|
||||
if options["continue_if_exists"]:
|
||||
continue
|
||||
raise CommandError(
|
||||
"Object already exists: {}".format(
|
||||
options["sepchar"].join(row[:2])))
|
||||
i += 1
|
||||
pbar.update(i)
|
||||
|
||||
pbar.finish()
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""Command entry point."""
|
||||
exts_pool.load_all()
|
||||
for filename in options["files"]:
|
||||
self._import(filename, options)
|
||||
@@ -12,3 +12,5 @@ django-passwords==0.3.4
|
||||
rfc6266
|
||||
progressbar==2.3
|
||||
djangorestframework==3.3.1
|
||||
django-subcommand2==0.1.1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user