prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Pre-set user's timezone
  **Is your feature request related to a problem? Please describe.**
  I signed up and saw you can set a timezone. It was set to UTC by default.
  
  **Describe the solution you'd like**
  JavaScript has an Internationalization API that returns timezones. At attempt should be made to pre-set this for less friction.
  
  ```
  const x = new Intl.DateTimeFormat()
  x.resolvedOptions().timeZone
  // => "Asia/Kolkata"
  ```
  
  
  Reading:
  
  - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
  - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/resolvedOptions
  
  --- 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/landing/register.py`
  Content:
  ```
  1 """ class views for login/register views """
  2 from django.contrib.auth import login
  3 from django.core.exceptions import PermissionDenied
  4 from django.shortcuts import get_object_or_404, redirect
  5 from django.template.response import TemplateResponse
  6 from django.utils.decorators import method_decorator
  7 from django.views import View
  8 from django.views.decorators.debug import sensitive_variables, sensitive_post_parameters
  9 
  10 from bookwyrm import emailing, forms, models
  11 from bookwyrm.settings import DOMAIN
  12 
  13 
  14 # pylint: disable=no-self-use
  15 class Register(View):
  16     """register a user"""
  17 
  18     def get(self, request):  # pylint: disable=unused-argument
  19         """whether or not you're logged in, just go to the home view"""
  20         return redirect("/")
  21 
  22     @sensitive_variables("password")
  23     @method_decorator(sensitive_post_parameters("password"))
  24     def post(self, request):
  25         """join the server"""
  26         settings = models.SiteSettings.get()
  27         # no registration allowed when the site is being installed
  28         if settings.install_mode:
  29             raise PermissionDenied()
  30 
  31         if not settings.allow_registration:
  32             invite_code = request.POST.get("invite_code")
  33 
  34             if not invite_code:
  35                 raise PermissionDenied()
  36 
  37             invite = get_object_or_404(models.SiteInvite, code=invite_code)
  38             if not invite.valid():
  39                 raise PermissionDenied()
  40         else:
  41             invite = None
  42 
  43         form = forms.RegisterForm(request.POST)
  44         if not form.is_valid():
  45             data = {
  46                 "login_form": forms.LoginForm(),
  47                 "register_form": form,
  48                 "invite": invite,
  49                 "valid": invite.valid() if invite else True,
  50             }
  51             if invite:
  52                 return TemplateResponse(request, "landing/invite.html", data)
  53             return TemplateResponse(request, "landing/login.html", data)
  54 
  55         localname = form.data["localname"].strip()
  56         email = form.data["email"]
  57         password = form.data["password"]
  58 
  59         # make sure the email isn't blocked as spam
  60         email_domain = email.split("@")[-1]
  61         if models.EmailBlocklist.objects.filter(domain=email_domain).exists():
  62             # treat this like a successful registration, but don't do anything
  63             return redirect("confirm-email")
  64 
  65         username = f"{localname}@{DOMAIN}"
  66         user = models.User.objects.create_user(
  67             username,
  68             email,
  69             password,
  70             localname=localname,
  71             local=True,
  72             deactivation_reason="pending" if settings.require_confirm_email else None,
  73             is_active=not settings.require_confirm_email,
  74         )
  75         if invite:
  76             invite.times_used += 1
  77             invite.invitees.add(user)
  78             invite.save()
  79 
  80         if settings.require_confirm_email:
  81             emailing.email_confirmation_email(user)
  82             return redirect("confirm-email")
  83 
  84         login(request, user)
  85         return redirect("get-started-profile")
  86 
  87 
  88 class ConfirmEmailCode(View):
  89     """confirm email address"""
  90 
  91     def get(self, request, code):  # pylint: disable=unused-argument
  92         """you got the code! good work"""
  93         settings = models.SiteSettings.get()
  94         if request.user.is_authenticated:
  95             return redirect("/")
  96 
  97         if not settings.require_confirm_email:
  98             return redirect("login")
  99 
  100         # look up the user associated with this code
  101         try:
  102             user = models.User.objects.get(confirmation_code=code)
  103         except models.User.DoesNotExist:
  104             return TemplateResponse(
  105                 request, "confirm_email/confirm_email.html", {"valid": False}
  106             )
  107         # update the user
  108         user.reactivate()
  109         # direct the user to log in
  110         return redirect("login", confirmed="confirmed")
  111 
  112 
  113 class ConfirmEmail(View):
  114     """enter code to confirm email address"""
  115 
  116     def get(self, request):  # pylint: disable=unused-argument
  117         """you need a code! keep looking"""
  118         settings = models.SiteSettings.get()
  119         if request.user.is_authenticated or not settings.require_confirm_email:
  120             return redirect("/")
  121 
  122         return TemplateResponse(
  123             request, "confirm_email/confirm_email.html", {"valid": True}
  124         )
  125 
  126     def post(self, request):
  127         """same as clicking the link"""
  128         code = request.POST.get("code")
  129         return ConfirmEmailCode().get(request, code)
  130 
  131 
  132 class ResendConfirmEmail(View):
  133     """you probably didn't get the email because celery is slow but you can try this"""
  134 
  135     def get(self, request):
  136         """resend link landing page"""
  137         return TemplateResponse(request, "confirm_email/resend.html")
  138 
  139     def post(self, request):
  140         """resend confirmation link"""
  141         email = request.POST.get("email")
  142         try:
  143             user = models.User.objects.get(email=email)
  144             emailing.email_confirmation_email(user)
  145         except models.User.DoesNotExist:
  146             pass
  147 
  148         return TemplateResponse(
  149             request, "confirm_email/confirm_email.html", {"valid": True}
  150         )
  151
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/bookwyrm/views/landing/register.py b/bookwyrm/views/landing/register.py
  --- a/bookwyrm/views/landing/register.py
  +++ b/bookwyrm/views/landing/register.py
  @@ -1,4 +1,5 @@
   """ class views for login/register views """
  +import pytz
   from django.contrib.auth import login
   from django.core.exceptions import PermissionDenied
   from django.shortcuts import get_object_or_404, redirect
  @@ -55,6 +56,10 @@
           localname = form.data["localname"].strip()
           email = form.data["email"]
           password = form.data["password"]
  +        try:
  +            preferred_timezone = pytz.timezone(form.data.get("preferred_timezone"))
  +        except pytz.exceptions.UnknownTimeZoneError:
  +            preferred_timezone = pytz.utc
   
           # make sure the email isn't blocked as spam
           email_domain = email.split("@")[-1]
  @@ -71,6 +76,7 @@
               local=True,
               deactivation_reason="pending" if settings.require_confirm_email else None,
               is_active=not settings.require_confirm_email,
  +            preferred_timezone=preferred_timezone,
           )
           if invite:
               invite.times_used += 1
  
verification_info: {"golden_diff": "diff --git a/bookwyrm/views/landing/register.py b/bookwyrm/views/landing/register.py\n--- a/bookwyrm/views/landing/register.py\n+++ b/bookwyrm/views/landing/register.py\n@@ -1,4 +1,5 @@\n \"\"\" class views for login/register views \"\"\"\n+import pytz\n from django.contrib.auth import login\n from django.core.exceptions import PermissionDenied\n from django.shortcuts import get_object_or_404, redirect\n@@ -55,6 +56,10 @@\n         localname = form.data[\"localname\"].strip()\n         email = form.data[\"email\"]\n         password = form.data[\"password\"]\n+        try:\n+            preferred_timezone = pytz.timezone(form.data.get(\"preferred_timezone\"))\n+        except pytz.exceptions.UnknownTimeZoneError:\n+            preferred_timezone = pytz.utc\n \n         # make sure the email isn't blocked as spam\n         email_domain = email.split(\"@\")[-1]\n@@ -71,6 +76,7 @@\n             local=True,\n             deactivation_reason=\"pending\" if settings.require_confirm_email else None,\n             is_active=not settings.require_confirm_email,\n+            preferred_timezone=preferred_timezone,\n         )\n         if invite:\n             invite.times_used += 1\n", "issue": "Pre-set user's timezone\n**Is your feature request related to a problem? Please describe.**\r\nI signed up and saw you can set a timezone. It was set to UTC by default.\r\n\r\n**Describe the solution you'd like**\r\nJavaScript has an Internationalization API that returns timezones. At attempt should be made to pre-set this for less friction.\r\n\r\n```\r\nconst x = new Intl.DateTimeFormat()\r\nx.resolvedOptions().timeZone\r\n// => \"Asia/Kolkata\"\r\n```\r\n\r\n\r\nReading:\r\n\r\n- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\r\n- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/resolvedOptions\n", "before_files": [{"content": "\"\"\" class views for login/register views \"\"\"\nfrom django.contrib.auth import login\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.utils.decorators import method_decorator\nfrom django.views import View\nfrom django.views.decorators.debug import sensitive_variables, sensitive_post_parameters\n\nfrom bookwyrm import emailing, forms, models\nfrom bookwyrm.settings import DOMAIN\n\n\n# pylint: disable=no-self-use\nclass Register(View):\n    \"\"\"register a user\"\"\"\n\n    def get(self, request):  # pylint: disable=unused-argument\n        \"\"\"whether or not you're logged in, just go to the home view\"\"\"\n        return redirect(\"/\")\n\n    @sensitive_variables(\"password\")\n    @method_decorator(sensitive_post_parameters(\"password\"))\n    def post(self, request):\n        \"\"\"join the server\"\"\"\n        settings = models.SiteSettings.get()\n        # no registration allowed when the site is being installed\n        if settings.install_mode:\n            raise PermissionDenied()\n\n        if not settings.allow_registration:\n            invite_code = request.POST.get(\"invite_code\")\n\n            if not invite_code:\n                raise PermissionDenied()\n\n            invite = get_object_or_404(models.SiteInvite, code=invite_code)\n            if not invite.valid():\n                raise PermissionDenied()\n        else:\n            invite = None\n\n        form = forms.RegisterForm(request.POST)\n        if not form.is_valid():\n            data = {\n                \"login_form\": forms.LoginForm(),\n                \"register_form\": form,\n                \"invite\": invite,\n                \"valid\": invite.valid() if invite else True,\n            }\n            if invite:\n                return TemplateResponse(request, \"landing/invite.html\", data)\n            return TemplateResponse(request, \"landing/login.html\", data)\n\n        localname = form.data[\"localname\"].strip()\n        email = form.data[\"email\"]\n        password = form.data[\"password\"]\n\n        # make sure the email isn't blocked as spam\n        email_domain = email.split(\"@\")[-1]\n        if models.EmailBlocklist.objects.filter(domain=email_domain).exists():\n            # treat this like a successful registration, but don't do anything\n            return redirect(\"confirm-email\")\n\n        username = f\"{localname}@{DOMAIN}\"\n        user = models.User.objects.create_user(\n            username,\n            email,\n            password,\n            localname=localname,\n            local=True,\n            deactivation_reason=\"pending\" if settings.require_confirm_email else None,\n            is_active=not settings.require_confirm_email,\n        )\n        if invite:\n            invite.times_used += 1\n            invite.invitees.add(user)\n            invite.save()\n\n        if settings.require_confirm_email:\n            emailing.email_confirmation_email(user)\n            return redirect(\"confirm-email\")\n\n        login(request, user)\n        return redirect(\"get-started-profile\")\n\n\nclass ConfirmEmailCode(View):\n    \"\"\"confirm email address\"\"\"\n\n    def get(self, request, code):  # pylint: disable=unused-argument\n        \"\"\"you got the code! good work\"\"\"\n        settings = models.SiteSettings.get()\n        if request.user.is_authenticated:\n            return redirect(\"/\")\n\n        if not settings.require_confirm_email:\n            return redirect(\"login\")\n\n        # look up the user associated with this code\n        try:\n            user = models.User.objects.get(confirmation_code=code)\n        except models.User.DoesNotExist:\n            return TemplateResponse(\n                request, \"confirm_email/confirm_email.html\", {\"valid\": False}\n            )\n        # update the user\n        user.reactivate()\n        # direct the user to log in\n        return redirect(\"login\", confirmed=\"confirmed\")\n\n\nclass ConfirmEmail(View):\n    \"\"\"enter code to confirm email address\"\"\"\n\n    def get(self, request):  # pylint: disable=unused-argument\n        \"\"\"you need a code! keep looking\"\"\"\n        settings = models.SiteSettings.get()\n        if request.user.is_authenticated or not settings.require_confirm_email:\n            return redirect(\"/\")\n\n        return TemplateResponse(\n            request, \"confirm_email/confirm_email.html\", {\"valid\": True}\n        )\n\n    def post(self, request):\n        \"\"\"same as clicking the link\"\"\"\n        code = request.POST.get(\"code\")\n        return ConfirmEmailCode().get(request, code)\n\n\nclass ResendConfirmEmail(View):\n    \"\"\"you probably didn't get the email because celery is slow but you can try this\"\"\"\n\n    def get(self, request):\n        \"\"\"resend link landing page\"\"\"\n        return TemplateResponse(request, \"confirm_email/resend.html\")\n\n    def post(self, request):\n        \"\"\"resend confirmation link\"\"\"\n        email = request.POST.get(\"email\")\n        try:\n            user = models.User.objects.get(email=email)\n            emailing.email_confirmation_email(user)\n        except models.User.DoesNotExist:\n            pass\n\n        return TemplateResponse(\n            request, \"confirm_email/confirm_email.html\", {\"valid\": True}\n        )\n", "path": "bookwyrm/views/landing/register.py"}], "after_files": [{"content": "\"\"\" class views for login/register views \"\"\"\nimport pytz\nfrom django.contrib.auth import login\nfrom django.core.exceptions import PermissionDenied\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.utils.decorators import method_decorator\nfrom django.views import View\nfrom django.views.decorators.debug import sensitive_variables, sensitive_post_parameters\n\nfrom bookwyrm import emailing, forms, models\nfrom bookwyrm.settings import DOMAIN\n\n\n# pylint: disable=no-self-use\nclass Register(View):\n    \"\"\"register a user\"\"\"\n\n    def get(self, request):  # pylint: disable=unused-argument\n        \"\"\"whether or not you're logged in, just go to the home view\"\"\"\n        return redirect(\"/\")\n\n    @sensitive_variables(\"password\")\n    @method_decorator(sensitive_post_parameters(\"password\"))\n    def post(self, request):\n        \"\"\"join the server\"\"\"\n        settings = models.SiteSettings.get()\n        # no registration allowed when the site is being installed\n        if settings.install_mode:\n            raise PermissionDenied()\n\n        if not settings.allow_registration:\n            invite_code = request.POST.get(\"invite_code\")\n\n            if not invite_code:\n                raise PermissionDenied()\n\n            invite = get_object_or_404(models.SiteInvite, code=invite_code)\n            if not invite.valid():\n                raise PermissionDenied()\n        else:\n            invite = None\n\n        form = forms.RegisterForm(request.POST)\n        if not form.is_valid():\n            data = {\n                \"login_form\": forms.LoginForm(),\n                \"register_form\": form,\n                \"invite\": invite,\n                \"valid\": invite.valid() if invite else True,\n            }\n            if invite:\n                return TemplateResponse(request, \"landing/invite.html\", data)\n            return TemplateResponse(request, \"landing/login.html\", data)\n\n        localname = form.data[\"localname\"].strip()\n        email = form.data[\"email\"]\n        password = form.data[\"password\"]\n        try:\n            preferred_timezone = pytz.timezone(form.data.get(\"preferred_timezone\"))\n        except pytz.exceptions.UnknownTimeZoneError:\n            preferred_timezone = pytz.utc\n\n        # make sure the email isn't blocked as spam\n        email_domain = email.split(\"@\")[-1]\n        if models.EmailBlocklist.objects.filter(domain=email_domain).exists():\n            # treat this like a successful registration, but don't do anything\n            return redirect(\"confirm-email\")\n\n        username = f\"{localname}@{DOMAIN}\"\n        user = models.User.objects.create_user(\n            username,\n            email,\n            password,\n            localname=localname,\n            local=True,\n            deactivation_reason=\"pending\" if settings.require_confirm_email else None,\n            is_active=not settings.require_confirm_email,\n            preferred_timezone=preferred_timezone,\n        )\n        if invite:\n            invite.times_used += 1\n            invite.invitees.add(user)\n            invite.save()\n\n        if settings.require_confirm_email:\n            emailing.email_confirmation_email(user)\n            return redirect(\"confirm-email\")\n\n        login(request, user)\n        return redirect(\"get-started-profile\")\n\n\nclass ConfirmEmailCode(View):\n    \"\"\"confirm email address\"\"\"\n\n    def get(self, request, code):  # pylint: disable=unused-argument\n        \"\"\"you got the code! good work\"\"\"\n        settings = models.SiteSettings.get()\n        if request.user.is_authenticated:\n            return redirect(\"/\")\n\n        if not settings.require_confirm_email:\n            return redirect(\"login\")\n\n        # look up the user associated with this code\n        try:\n            user = models.User.objects.get(confirmation_code=code)\n        except models.User.DoesNotExist:\n            return TemplateResponse(\n                request, \"confirm_email/confirm_email.html\", {\"valid\": False}\n            )\n        # update the user\n        user.is_active = True\n        user.deactivation_reason = None\n        user.save(broadcast=False, update_fields=[\"is_active\", \"deactivation_reason\"])\n        # direct the user to log in\n        return redirect(\"login\", confirmed=\"confirmed\")\n\n\nclass ConfirmEmail(View):\n    \"\"\"enter code to confirm email address\"\"\"\n\n    def get(self, request):  # pylint: disable=unused-argument\n        \"\"\"you need a code! keep looking\"\"\"\n        settings = models.SiteSettings.get()\n        if request.user.is_authenticated or not settings.require_confirm_email:\n            return redirect(\"/\")\n\n        return TemplateResponse(\n            request, \"confirm_email/confirm_email.html\", {\"valid\": True}\n        )\n\n    def post(self, request):\n        \"\"\"same as clicking the link\"\"\"\n        code = request.POST.get(\"code\")\n        return ConfirmEmailCode().get(request, code)\n\n\nclass ResendConfirmEmail(View):\n    \"\"\"you probably didn't get the email because celery is slow but you can try this\"\"\"\n\n    def get(self, request):\n        \"\"\"resend link landing page\"\"\"\n        return TemplateResponse(request, \"confirm_email/resend.html\")\n\n    def post(self, request):\n        \"\"\"resend confirmation link\"\"\"\n        email = request.POST.get(\"email\")\n        try:\n            user = models.User.objects.get(email=email)\n            emailing.email_confirmation_email(user)\n        except models.User.DoesNotExist:\n            pass\n\n        return TemplateResponse(\n            request, \"confirm_email/confirm_email.html\", {\"valid\": True}\n        )\n", "path": "bookwyrm/views/landing/register.py"}]}