We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Exported CSV file does not seem to contain information on what shelf my books are on
**Describe the bug**
I exported the CSV-file from my account on bookwyrm.social, and it does not seem to contain information on what books I've read and what I want to read and what I am currently reading (Shelves)

**To Reproduce**
Steps to reproduce the behavior:
1. Go to settings
2. click on  CSV export
3. Click on "Download file"
4. No apparent status-column in the exported csv-file

**Expected behavior**
A column indicating what shelf a book is on

**Instance**
Exported from bookwyrm.social

**Desktop (please complete the following information):**
    - OS: MacOS
    - Browser Firefox
    - Version 113b

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bookwyrm/views/preferences/export.py`
Content:
```
1 """ Let users export their book data """
2 from datetime import timedelta
3 import csv
4 import io
5 
6 from django.contrib.auth.decorators import login_required
7 from django.core.paginator import Paginator
8 from django.db.models import Q
9 from django.http import HttpResponse
10 from django.template.response import TemplateResponse
11 from django.utils import timezone
12 from django.views import View
13 from django.utils.decorators import method_decorator
14 from django.shortcuts import redirect
15 
16 from bookwyrm import models
17 from bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob
18 from bookwyrm.settings import PAGE_LENGTH
19 
20 # pylint: disable=no-self-use,too-many-locals
21 @method_decorator(login_required, name="dispatch")
22 class Export(View):
23     """Let users export data"""
24 
25     def get(self, request):
26         """Request csv file"""
27         return TemplateResponse(request, "preferences/export.html")
28 
29     def post(self, request):
30         """Download the csv file of a user's book data"""
31         books = models.Edition.viewer_aware_objects(request.user)
32         books_shelves = books.filter(Q(shelves__user=request.user)).distinct()
33         books_readthrough = books.filter(Q(readthrough__user=request.user)).distinct()
34         books_review = books.filter(Q(review__user=request.user)).distinct()
35         books_comment = books.filter(Q(comment__user=request.user)).distinct()
36         books_quotation = books.filter(Q(quotation__user=request.user)).distinct()
37 
38         books = set(
39             list(books_shelves)
40             + list(books_readthrough)
41             + list(books_review)
42             + list(books_comment)
43             + list(books_quotation)
44         )
45 
46         csv_string = io.StringIO()
47         writer = csv.writer(csv_string)
48 
49         deduplication_fields = [
50             f.name
51             for f in models.Edition._meta.get_fields()  # pylint: disable=protected-access
52             if getattr(f, "deduplication_field", False)
53         ]
54         fields = (
55             ["title", "author_text"]
56             + deduplication_fields
57             + ["start_date", "finish_date", "stopped_date"]
58             + ["rating", "review_name", "review_cw", "review_content"]
59         )
60         writer.writerow(fields)
61 
62         for book in books:
63             # I think this is more efficient than doing a subquery in the view? but idk
64             review_rating = (
65                 models.Review.objects.filter(
66                     user=request.user, book=book, rating__isnull=False
67                 )
68                 .order_by("-published_date")
69                 .first()
70             )
71 
72             book.rating = review_rating.rating if review_rating else None
73 
74             readthrough = (
75                 models.ReadThrough.objects.filter(user=request.user, book=book)
76                 .order_by("-start_date", "-finish_date")
77                 .first()
78             )
79             if readthrough:
80                 book.start_date = (
81                     readthrough.start_date.date() if readthrough.start_date else None
82                 )
83                 book.finish_date = (
84                     readthrough.finish_date.date() if readthrough.finish_date else None
85                 )
86                 book.stopped_date = (
87                     readthrough.stopped_date.date()
88                     if readthrough.stopped_date
89                     else None
90                 )
91 
92             review = (
93                 models.Review.objects.filter(
94                     user=request.user, book=book, content__isnull=False
95                 )
96                 .order_by("-published_date")
97                 .first()
98             )
99             if review:
100                 book.review_name = review.name
101                 book.review_cw = review.content_warning
102                 book.review_content = review.raw_content
103             writer.writerow([getattr(book, field, "") or "" for field in fields])
104 
105         return HttpResponse(
106             csv_string.getvalue(),
107             content_type="text/csv",
108             headers={
109                 "Content-Disposition": 'attachment; filename="bookwyrm-export.csv"'
110             },
111         )
112 
113 
114 # pylint: disable=no-self-use
115 @method_decorator(login_required, name="dispatch")
116 class ExportUser(View):
117     """Let users export user data to import into another Bookwyrm instance"""
118 
119     def get(self, request):
120         """Request tar file"""
121 
122         jobs = BookwyrmExportJob.objects.filter(user=request.user).order_by(
123             "-created_date"
124         )
125         site = models.SiteSettings.objects.get()
126         hours = site.user_import_time_limit
127         allowed = (
128             jobs.first().created_date < timezone.now() - timedelta(hours=hours)
129             if jobs.first()
130             else True
131         )
132         next_available = (
133             jobs.first().created_date + timedelta(hours=hours) if not allowed else False
134         )
135         paginated = Paginator(jobs, PAGE_LENGTH)
136         page = paginated.get_page(request.GET.get("page"))
137         data = {
138             "jobs": page,
139             "next_available": next_available,
140             "page_range": paginated.get_elided_page_range(
141                 page.number, on_each_side=2, on_ends=1
142             ),
143         }
144 
145         return TemplateResponse(request, "preferences/export-user.html", data)
146 
147     def post(self, request):
148         """Download the json file of a user's data"""
149 
150         job = BookwyrmExportJob.objects.create(user=request.user)
151         job.start_job()
152 
153         return redirect("prefs-user-export")
154 
155 
156 @method_decorator(login_required, name="dispatch")
157 class ExportArchive(View):
158     """Serve the archive file"""
159 
160     def get(self, request, archive_id):
161         """download user export file"""
162         export = BookwyrmExportJob.objects.get(task_id=archive_id, user=request.user)
163         return HttpResponse(
164             export.export_data,
165             content_type="application/gzip",
166             headers={
167                 "Content-Disposition": 'attachment; filename="bookwyrm-account-export.tar.gz"'  # pylint: disable=line-too-long
168             },
169         )
170
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bookwyrm/views/preferences/export.py b/bookwyrm/views/preferences/export.py
--- a/bookwyrm/views/preferences/export.py
+++ b/bookwyrm/views/preferences/export.py
@@ -17,6 +17,7 @@
 from bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob
 from bookwyrm.settings import PAGE_LENGTH
 
+
 # pylint: disable=no-self-use,too-many-locals
 @method_decorator(login_required, name="dispatch")
 class Export(View):
@@ -54,8 +55,19 @@
         fields = (
             ["title", "author_text"]
             + deduplication_fields
-            + ["start_date", "finish_date", "stopped_date"]
-            + ["rating", "review_name", "review_cw", "review_content"]
+            + [
+                "start_date",
+                "finish_date",
+                "stopped_date",
+                "rating",
+                "review_name",
+                "review_cw",
+                "review_content",
+                "review_published",
+                "shelf",
+                "shelf_name",
+                "shelf_date",
+            ]
         )
         writer.writerow(fields)
 
@@ -97,9 +109,27 @@
                 .first()
             )
             if review:
+                book.review_published = (
+                    review.published_date.date() if review.published_date else None
+                )
                 book.review_name = review.name
                 book.review_cw = review.content_warning
-                book.review_content = review.raw_content
+                book.review_content = (
+                    review.raw_content if review.raw_content else review.content
+                )  # GoodReads imported reviews do not have raw_content, but content.
+
+            shelfbook = (
+                models.ShelfBook.objects.filter(user=request.user, book=book)
+                .order_by("-shelved_date", "-created_date", "-updated_date")
+                .last()
+            )
+            if shelfbook:
+                book.shelf = shelfbook.shelf.identifier
+                book.shelf_name = shelfbook.shelf.name
+                book.shelf_date = (
+                    shelfbook.shelved_date.date() if shelfbook.shelved_date else None
+                )
+
             writer.writerow([getattr(book, field, "") or "" for field in fields])
 
         return HttpResponse(

{"golden_diff": "diff --git a/bookwyrm/views/preferences/export.py b/bookwyrm/views/preferences/export.py\n--- a/bookwyrm/views/preferences/export.py\n+++ b/bookwyrm/views/preferences/export.py\n@@ -17,6 +17,7 @@\n from bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob\n from bookwyrm.settings import PAGE_LENGTH\n \n+\n # pylint: disable=no-self-use,too-many-locals\n @method_decorator(login_required, name=\"dispatch\")\n class Export(View):\n@@ -54,8 +55,19 @@\n         fields = (\n             [\"title\", \"author_text\"]\n             + deduplication_fields\n-            + [\"start_date\", \"finish_date\", \"stopped_date\"]\n-            + [\"rating\", \"review_name\", \"review_cw\", \"review_content\"]\n+            + [\n+                \"start_date\",\n+                \"finish_date\",\n+                \"stopped_date\",\n+                \"rating\",\n+                \"review_name\",\n+                \"review_cw\",\n+                \"review_content\",\n+                \"review_published\",\n+                \"shelf\",\n+                \"shelf_name\",\n+                \"shelf_date\",\n+            ]\n         )\n         writer.writerow(fields)\n \n@@ -97,9 +109,27 @@\n                 .first()\n             )\n             if review:\n+                book.review_published = (\n+                    review.published_date.date() if review.published_date else None\n+                )\n                 book.review_name = review.name\n                 book.review_cw = review.content_warning\n-                book.review_content = review.raw_content\n+                book.review_content = (\n+                    review.raw_content if review.raw_content else review.content\n+                )  # GoodReads imported reviews do not have raw_content, but content.\n+\n+            shelfbook = (\n+                models.ShelfBook.objects.filter(user=request.user, book=book)\n+                .order_by(\"-shelved_date\", \"-created_date\", \"-updated_date\")\n+                .last()\n+            )\n+            if shelfbook:\n+                book.shelf = shelfbook.shelf.identifier\n+                book.shelf_name = shelfbook.shelf.name\n+                book.shelf_date = (\n+                    shelfbook.shelved_date.date() if shelfbook.shelved_date else None\n+                )\n+\n             writer.writerow([getattr(book, field, \"\") or \"\" for field in fields])\n \n         return HttpResponse(\n", "issue": "Exported CSV file does not seem to contain information on what shelf my books are on\n**Describe the bug**\r\nI exported the CSV-file from my account on bookwyrm.social, and it does not seem to contain information on what books I've read and what I want to read and what I am currently reading (Shelves)\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to settings\r\n2. click on  CSV export\r\n3. Click on \"Download file\"\r\n4. No apparent status-column in the exported csv-file\r\n\r\n**Expected behavior**\r\nA column indicating what shelf a book is on\r\n\r\n**Instance**\r\nExported from bookwyrm.social\r\n\r\n**Desktop (please complete the following information):**\r\n    - OS: MacOS\r\n    - Browser Firefox\r\n    - Version 113b\n", "before_files": [{"content": "\"\"\" Let users export their book data \"\"\"\nfrom datetime import timedelta\nimport csv\nimport io\n\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.paginator import Paginator\nfrom django.db.models import Q\nfrom django.http import HttpResponse\nfrom django.template.response import TemplateResponse\nfrom django.utils import timezone\nfrom django.views import View\nfrom django.utils.decorators import method_decorator\nfrom django.shortcuts import redirect\n\nfrom bookwyrm import models\nfrom bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob\nfrom bookwyrm.settings import PAGE_LENGTH\n\n# pylint: disable=no-self-use,too-many-locals\n@method_decorator(login_required, name=\"dispatch\")\nclass Export(View):\n    \"\"\"Let users export data\"\"\"\n\n    def get(self, request):\n        \"\"\"Request csv file\"\"\"\n        return TemplateResponse(request, \"preferences/export.html\")\n\n    def post(self, request):\n        \"\"\"Download the csv file of a user's book data\"\"\"\n        books = models.Edition.viewer_aware_objects(request.user)\n        books_shelves = books.filter(Q(shelves__user=request.user)).distinct()\n        books_readthrough = books.filter(Q(readthrough__user=request.user)).distinct()\n        books_review = books.filter(Q(review__user=request.user)).distinct()\n        books_comment = books.filter(Q(comment__user=request.user)).distinct()\n        books_quotation = books.filter(Q(quotation__user=request.user)).distinct()\n\n        books = set(\n            list(books_shelves)\n            + list(books_readthrough)\n            + list(books_review)\n            + list(books_comment)\n            + list(books_quotation)\n        )\n\n        csv_string = io.StringIO()\n        writer = csv.writer(csv_string)\n\n        deduplication_fields = [\n            f.name\n            for f in models.Edition._meta.get_fields()  # pylint: disable=protected-access\n            if getattr(f, \"deduplication_field\", False)\n        ]\n        fields = (\n            [\"title\", \"author_text\"]\n            + deduplication_fields\n            + [\"start_date\", \"finish_date\", \"stopped_date\"]\n            + [\"rating\", \"review_name\", \"review_cw\", \"review_content\"]\n        )\n        writer.writerow(fields)\n\n        for book in books:\n            # I think this is more efficient than doing a subquery in the view? but idk\n            review_rating = (\n                models.Review.objects.filter(\n                    user=request.user, book=book, rating__isnull=False\n                )\n                .order_by(\"-published_date\")\n                .first()\n            )\n\n            book.rating = review_rating.rating if review_rating else None\n\n            readthrough = (\n                models.ReadThrough.objects.filter(user=request.user, book=book)\n                .order_by(\"-start_date\", \"-finish_date\")\n                .first()\n            )\n            if readthrough:\n                book.start_date = (\n                    readthrough.start_date.date() if readthrough.start_date else None\n                )\n                book.finish_date = (\n                    readthrough.finish_date.date() if readthrough.finish_date else None\n                )\n                book.stopped_date = (\n                    readthrough.stopped_date.date()\n                    if readthrough.stopped_date\n                    else None\n                )\n\n            review = (\n                models.Review.objects.filter(\n                    user=request.user, book=book, content__isnull=False\n                )\n                .order_by(\"-published_date\")\n                .first()\n            )\n            if review:\n                book.review_name = review.name\n                book.review_cw = review.content_warning\n                book.review_content = review.raw_content\n            writer.writerow([getattr(book, field, \"\") or \"\" for field in fields])\n\n        return HttpResponse(\n            csv_string.getvalue(),\n            content_type=\"text/csv\",\n            headers={\n                \"Content-Disposition\": 'attachment; filename=\"bookwyrm-export.csv\"'\n            },\n        )\n\n\n# pylint: disable=no-self-use\n@method_decorator(login_required, name=\"dispatch\")\nclass ExportUser(View):\n    \"\"\"Let users export user data to import into another Bookwyrm instance\"\"\"\n\n    def get(self, request):\n        \"\"\"Request tar file\"\"\"\n\n        jobs = BookwyrmExportJob.objects.filter(user=request.user).order_by(\n            \"-created_date\"\n        )\n        site = models.SiteSettings.objects.get()\n        hours = site.user_import_time_limit\n        allowed = (\n            jobs.first().created_date < timezone.now() - timedelta(hours=hours)\n            if jobs.first()\n            else True\n        )\n        next_available = (\n            jobs.first().created_date + timedelta(hours=hours) if not allowed else False\n        )\n        paginated = Paginator(jobs, PAGE_LENGTH)\n        page = paginated.get_page(request.GET.get(\"page\"))\n        data = {\n            \"jobs\": page,\n            \"next_available\": next_available,\n            \"page_range\": paginated.get_elided_page_range(\n                page.number, on_each_side=2, on_ends=1\n            ),\n        }\n\n        return TemplateResponse(request, \"preferences/export-user.html\", data)\n\n    def post(self, request):\n        \"\"\"Download the json file of a user's data\"\"\"\n\n        job = BookwyrmExportJob.objects.create(user=request.user)\n        job.start_job()\n\n        return redirect(\"prefs-user-export\")\n\n\n@method_decorator(login_required, name=\"dispatch\")\nclass ExportArchive(View):\n    \"\"\"Serve the archive file\"\"\"\n\n    def get(self, request, archive_id):\n        \"\"\"download user export file\"\"\"\n        export = BookwyrmExportJob.objects.get(task_id=archive_id, user=request.user)\n        return HttpResponse(\n            export.export_data,\n            content_type=\"application/gzip\",\n            headers={\n                \"Content-Disposition\": 'attachment; filename=\"bookwyrm-account-export.tar.gz\"'  # pylint: disable=line-too-long\n            },\n        )\n", "path": "bookwyrm/views/preferences/export.py"}], "after_files": [{"content": "\"\"\" Let users export their book data \"\"\"\nfrom datetime import timedelta\nimport csv\nimport io\n\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.paginator import Paginator\nfrom django.db.models import Q\nfrom django.http import HttpResponse\nfrom django.template.response import TemplateResponse\nfrom django.utils import timezone\nfrom django.views import View\nfrom django.utils.decorators import method_decorator\nfrom django.shortcuts import redirect\n\nfrom bookwyrm import models\nfrom bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob\nfrom bookwyrm.settings import PAGE_LENGTH\n\n\n# pylint: disable=no-self-use,too-many-locals\n@method_decorator(login_required, name=\"dispatch\")\nclass Export(View):\n    \"\"\"Let users export data\"\"\"\n\n    def get(self, request):\n        \"\"\"Request csv file\"\"\"\n        return TemplateResponse(request, \"preferences/export.html\")\n\n    def post(self, request):\n        \"\"\"Download the csv file of a user's book data\"\"\"\n        books = models.Edition.viewer_aware_objects(request.user)\n        books_shelves = books.filter(Q(shelves__user=request.user)).distinct()\n        books_readthrough = books.filter(Q(readthrough__user=request.user)).distinct()\n        books_review = books.filter(Q(review__user=request.user)).distinct()\n        books_comment = books.filter(Q(comment__user=request.user)).distinct()\n        books_quotation = books.filter(Q(quotation__user=request.user)).distinct()\n\n        books = set(\n            list(books_shelves)\n            + list(books_readthrough)\n            + list(books_review)\n            + list(books_comment)\n            + list(books_quotation)\n        )\n\n        csv_string = io.StringIO()\n        writer = csv.writer(csv_string)\n\n        deduplication_fields = [\n            f.name\n            for f in models.Edition._meta.get_fields()  # pylint: disable=protected-access\n            if getattr(f, \"deduplication_field\", False)\n        ]\n        fields = (\n            [\"title\", \"author_text\"]\n            + deduplication_fields\n            + [\n                \"start_date\",\n                \"finish_date\",\n                \"stopped_date\",\n                \"rating\",\n                \"review_name\",\n                \"review_cw\",\n                \"review_content\",\n                \"review_published\",\n                \"shelf\",\n                \"shelf_name\",\n                \"shelf_date\",\n            ]\n        )\n        writer.writerow(fields)\n\n        for book in books:\n            # I think this is more efficient than doing a subquery in the view? but idk\n            review_rating = (\n                models.Review.objects.filter(\n                    user=request.user, book=book, rating__isnull=False\n                )\n                .order_by(\"-published_date\")\n                .first()\n            )\n\n            book.rating = review_rating.rating if review_rating else None\n\n            readthrough = (\n                models.ReadThrough.objects.filter(user=request.user, book=book)\n                .order_by(\"-start_date\", \"-finish_date\")\n                .first()\n            )\n            if readthrough:\n                book.start_date = (\n                    readthrough.start_date.date() if readthrough.start_date else None\n                )\n                book.finish_date = (\n                    readthrough.finish_date.date() if readthrough.finish_date else None\n                )\n                book.stopped_date = (\n                    readthrough.stopped_date.date()\n                    if readthrough.stopped_date\n                    else None\n                )\n\n            review = (\n                models.Review.objects.filter(\n                    user=request.user, book=book, content__isnull=False\n                )\n                .order_by(\"-published_date\")\n                .first()\n            )\n            if review:\n                book.review_published = (\n                    review.published_date.date() if review.published_date else None\n                )\n                book.review_name = review.name\n                book.review_cw = review.content_warning\n                book.review_content = (\n                    review.raw_content if review.raw_content else review.content\n                )  # GoodReads imported reviews do not have raw_content, but content.\n\n            shelfbook = (\n                models.ShelfBook.objects.filter(user=request.user, book=book)\n                .order_by(\"-shelved_date\", \"-created_date\", \"-updated_date\")\n                .last()\n            )\n            if shelfbook:\n                book.shelf = shelfbook.shelf.identifier\n                book.shelf_name = shelfbook.shelf.name\n                book.shelf_date = (\n                    shelfbook.shelved_date.date() if shelfbook.shelved_date else None\n                )\n\n            writer.writerow([getattr(book, field, \"\") or \"\" for field in fields])\n\n        return HttpResponse(\n            csv_string.getvalue(),\n            content_type=\"text/csv\",\n            headers={\n                \"Content-Disposition\": 'attachment; filename=\"bookwyrm-export.csv\"'\n            },\n        )\n\n\n# pylint: disable=no-self-use\n@method_decorator(login_required, name=\"dispatch\")\nclass ExportUser(View):\n    \"\"\"Let users export user data to import into another Bookwyrm instance\"\"\"\n\n    def get(self, request):\n        \"\"\"Request tar file\"\"\"\n\n        jobs = BookwyrmExportJob.objects.filter(user=request.user).order_by(\n            \"-created_date\"\n        )\n        site = models.SiteSettings.objects.get()\n        hours = site.user_import_time_limit\n        allowed = (\n            jobs.first().created_date < timezone.now() - timedelta(hours=hours)\n            if jobs.first()\n            else True\n        )\n        next_available = (\n            jobs.first().created_date + timedelta(hours=hours) if not allowed else False\n        )\n        paginated = Paginator(jobs, PAGE_LENGTH)\n        page = paginated.get_page(request.GET.get(\"page\"))\n        data = {\n            \"jobs\": page,\n            \"next_available\": next_available,\n            \"page_range\": paginated.get_elided_page_range(\n                page.number, on_each_side=2, on_ends=1\n            ),\n        }\n\n        return TemplateResponse(request, \"preferences/export-user.html\", data)\n\n    def post(self, request):\n        \"\"\"Download the json file of a user's data\"\"\"\n\n        job = BookwyrmExportJob.objects.create(user=request.user)\n        job.start_job()\n\n        return redirect(\"prefs-user-export\")\n\n\n@method_decorator(login_required, name=\"dispatch\")\nclass ExportArchive(View):\n    \"\"\"Serve the archive file\"\"\"\n\n    def get(self, request, archive_id):\n        \"\"\"download user export file\"\"\"\n        export = BookwyrmExportJob.objects.get(task_id=archive_id, user=request.user)\n        return HttpResponse(\n            export.export_data,\n            content_type=\"application/gzip\",\n            headers={\n                \"Content-Disposition\": 'attachment; filename=\"bookwyrm-account-export.tar.gz\"'  # pylint: disable=line-too-long\n            },\n        )\n", "path": "bookwyrm/views/preferences/export.py"}]}