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)))
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, }, )