Exemplo n.º 1
0
    def handle(self, *args, **options):
        src = options["src"]
        from_index = options.pop("from")
        to_index = options.pop("to")
        site_id = options.pop("site", None)
        permament = options.pop("permanent")

        dry_run = options.pop("dry_run", False) or options.pop(
            "dry-run", False)
        format_ = options.pop("format", None)
        ask = options.pop("ask")
        offset = options.pop("offset")
        limit = options.pop("limit")

        errors = []
        successes = 0
        skipped = 0
        total = 0
        site = None

        if site_id:
            site = Site.objects.get(id=site_id)

        if not os.path.exists(src):
            raise Exception("Missing file '{0}'".format(src))

        if not os.path.getsize(src) > 0:
            raise Exception("File '{0}' is empty".format(src))

        _, extension = os.path.splitext(src)
        extension = extension.lstrip(".")

        if not format_:
            format_ = extension

        if not get_format_cls_by_extension(format_):
            raise Exception("Invalid format '{0}'".format(extension))

        if extension in ["xls", "xlsx"]:
            mode = "rb"
        else:
            mode = "r"

        with open(src, mode) as fh:
            imported_data = tablib.Dataset().load(fh.read(), format=format_)

            sample_data = tablib.Dataset(
                *imported_data[:min(len(imported_data), 4)],
                headers=imported_data.headers)

            try:
                self.stdout.write("Sample data:")
                self.stdout.write(str(sample_data))
            except Exception:
                self.stdout.write("Warning: Cannot display sample data")

            self.stdout.write("--------------")

            if site:
                self.stdout.write("Using site: {0}".format(site.hostname))

            self.stdout.write("Importing redirects:")

            if offset:
                imported_data = imported_data[offset:]
            if limit:
                imported_data = imported_data[:limit]

            for row in imported_data:
                total += 1

                from_link = row[from_index]
                to_link = row[to_index]

                data = {
                    "old_path": from_link,
                    "redirect_link": to_link,
                    "is_permanent": permament,
                }

                if site:
                    data["site"] = site.pk

                form = RedirectForm(data)
                if not form.is_valid():
                    error = form.errors.as_text().replace("\n", "")
                    self.stdout.write(
                        "{}. Error: {} -> {} (Reason: {})".format(
                            total,
                            from_link,
                            to_link,
                            error,
                        ))
                    errors.append(error)
                    continue

                if ask:
                    answer = get_input(
                        "{}. Found {} -> {} Create? Y/n: ".format(
                            total,
                            from_link,
                            to_link,
                        ))

                    if answer != "Y":
                        skipped += 1
                        continue
                else:
                    self.stdout.write("{}. {} -> {}".format(
                        total,
                        from_link,
                        to_link,
                    ))

                if dry_run:
                    successes += 1
                    continue

                form.save()
                successes += 1

        self.stdout.write("\n")
        self.stdout.write("Found: {}".format(total))
        self.stdout.write("Created: {}".format(successes))
        self.stdout.write("Skipped : {}".format(skipped))
        self.stdout.write("Errors: {}".format(len(errors)))
Exemplo n.º 2
0
def start_import(request):
    supported_extensions = get_supported_extensions()
    from_encoding = "utf-8"

    query_string = request.GET.get('q', "")

    if request.POST or request.FILES:
        form_kwargs = {}
        form = ImportForm(supported_extensions, request.POST or None,
                          request.FILES or None, **form_kwargs)
    else:
        form = ImportForm(supported_extensions)

    if not request.FILES or not form.is_valid():
        return render(
            request,
            "wagtailredirects/choose_import_file.html",
            {
                'search_form':
                SearchForm(data=dict(q=query_string) if query_string else None,
                           placeholder=_("Search redirects")),
                "form":
                form,
            },
        )

    import_file = form.cleaned_data["import_file"]

    _name, extension = os.path.splitext(import_file.name)
    extension = extension.lstrip(".")

    if extension not in supported_extensions:
        messages.error(
            request,
            _('File format of type "{}" is not supported').format(extension))
        return redirect('wagtailredirects:start_import')

    import_format_cls = get_format_cls_by_extension(extension)
    input_format = import_format_cls()
    file_storage = write_to_file_storage(import_file, input_format)

    try:
        data = file_storage.read(input_format.get_read_mode())
        if not input_format.is_binary() and from_encoding:
            data = force_str(data, from_encoding)
        dataset = input_format.create_dataset(data)
    except UnicodeDecodeError as e:
        messages.error(request,
                       _("Imported file has a wrong encoding: %s") % e)
        return redirect('wagtailredirects:start_import')
    except Exception as e:  # pragma: no cover
        messages.error(
            request,
            _("%(error)s encountered while trying to read file: %(filename)s")
            % {
                'error': type(e).__name__,
                'filename': import_file.name
            })
        return redirect('wagtailredirects:start_import')

    initial = {
        "import_file_name": file_storage.name,
        "original_file_name": import_file.name,
        "input_format": get_import_formats().index(import_format_cls),
    }

    return render(
        request,
        "wagtailredirects/confirm_import.html",
        {
            "form": ConfirmImportForm(dataset.headers, initial=initial),
            "dataset": dataset,
        },
    )