From 37a698c77b0fe8426641864e837a300d37704176 Mon Sep 17 00:00:00 2001 From: Scot Hacker Date: Sun, 10 Mar 2019 14:23:17 -0700 Subject: [PATCH] Working browser-upload view --- todo/operations/csv_importer.py | 1 + todo/templates/todo/import_csv.html | 80 +++++++++++++++++++++++++++++ todo/urls.py | 5 ++ todo/views/__init__.py | 1 + todo/views/import_csv.py | 22 ++++++++ 5 files changed, 109 insertions(+) create mode 100644 todo/templates/todo/import_csv.html create mode 100644 todo/views/import_csv.py diff --git a/todo/operations/csv_importer.py b/todo/operations/csv_importer.py index a7e78a9..62e777e 100644 --- a/todo/operations/csv_importer.py +++ b/todo/operations/csv_importer.py @@ -68,6 +68,7 @@ class CSVImporter: self.summary_msgs.append(f"\nProcessed {self.line_count} CSV rows") self.summary_msgs.append(f"Upserted {self.upsert_count} rows") + self.summary_msgs.append(f"Skipped {self.line_count - self.upsert_count} rows") _res = { "errors": self.error_msgs, diff --git a/todo/templates/todo/import_csv.html b/todo/templates/todo/import_csv.html new file mode 100644 index 0000000..ec91b45 --- /dev/null +++ b/todo/templates/todo/import_csv.html @@ -0,0 +1,80 @@ +{% extends "todo/base.html" %} +{% load static %} + +{% block title %}Import CSV{% endblock %} + +{% block content %} +

+ Import CSV +

+ +

+ Batch-import tasks by uploading a specifically-formatted CSV. + See documentation for formatting rules. + Successs and failures will be reported here. +

+ + {% if results %} +
+
+ Results of CSV upload +
+
+ +

+ Summary: +

+
    + {% for line in results.summaries %} +
  • {{ line }}
  • + {% endfor %} +
+ +

+ Upserts (tasks created or updated): +

+
    + {% for line in results.upserts %} +
  • {{ line }}
  • + {% endfor %} +
+ +

+ Errors (tasks NOT created or updated): +

+
    + {% for error_row in results.errors %} + {% for k, error_list in error_row.items %} +
  • CSV row {{ k }}
  • +
      + {% for err in error_list %} +
    • {{ err }}
    • + {% endfor %} +
    + {% endfor %} + + {% endfor %} +
+ + +
+
+ {% endif %} + + +
+
+ Upload Tasks +
+
+
+ {% csrf_token %} +
+ +
+ +
+
+
+ +{% endblock %} diff --git a/todo/urls.py b/todo/urls.py index 2c97a8d..7e5d2a6 100644 --- a/todo/urls.py +++ b/todo/urls.py @@ -70,4 +70,9 @@ urlpatterns = [ 'search/', views.search, name="search"), + + path( + 'import_csv/', + views.import_csv, + name="import_csv"), ] diff --git a/todo/views/__init__.py b/todo/views/__init__.py index c36bb65..4c5777d 100644 --- a/todo/views/__init__.py +++ b/todo/views/__init__.py @@ -8,3 +8,4 @@ from todo.views.reorder_tasks import reorder_tasks # noqa: F401 from todo.views.search import search # noqa: F401 from todo.views.task_detail import task_detail # noqa: F401 from todo.views.toggle_done import toggle_done # noqa: F401 +from todo.views.import_csv import import_csv # noqa: F401 diff --git a/todo/views/import_csv.py b/todo/views/import_csv.py new file mode 100644 index 0000000..50db211 --- /dev/null +++ b/todo/views/import_csv.py @@ -0,0 +1,22 @@ +from django.contrib.auth.decorators import login_required, user_passes_test +from django.http import HttpResponse +from django.shortcuts import render +from todo.operations.csv_importer import CSVImporter + +from todo.utils import staff_check + +@login_required +@user_passes_test(staff_check) +def import_csv(request) -> HttpResponse: + """Import a specifically formatted CSV into stored tasks. + """ + + ctx = {} + + if request.method == "POST": + filepath = request.FILES.get('csvfile') + importer = CSVImporter() + results = importer.upsert(filepath) + ctx["results"] = results + + return render(request, "todo/import_csv.html", context=ctx)