aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/home/views
diff options
context:
space:
mode:
Diffstat (limited to 'pydis_site/apps/home/views')
-rw-r--r--pydis_site/apps/home/views/__init__.py3
-rw-r--r--pydis_site/apps/home/views/account/__init__.py4
-rw-r--r--pydis_site/apps/home/views/account/delete.py37
-rw-r--r--pydis_site/apps/home/views/account/settings.py59
-rw-r--r--pydis_site/apps/home/views/home.py4
5 files changed, 104 insertions, 3 deletions
diff --git a/pydis_site/apps/home/views/__init__.py b/pydis_site/apps/home/views/__init__.py
index 971d73a3..801fd398 100644
--- a/pydis_site/apps/home/views/__init__.py
+++ b/pydis_site/apps/home/views/__init__.py
@@ -1,3 +1,4 @@
+from .account import DeleteView as AccountDeleteView, SettingsView as AccountSettingsView
from .home import HomeView
-__all__ = ["HomeView"]
+__all__ = ["AccountDeleteView", "AccountSettingsView", "HomeView"]
diff --git a/pydis_site/apps/home/views/account/__init__.py b/pydis_site/apps/home/views/account/__init__.py
new file mode 100644
index 00000000..3b3250ea
--- /dev/null
+++ b/pydis_site/apps/home/views/account/__init__.py
@@ -0,0 +1,4 @@
+from .delete import DeleteView
+from .settings import SettingsView
+
+__all__ = ["DeleteView", "SettingsView"]
diff --git a/pydis_site/apps/home/views/account/delete.py b/pydis_site/apps/home/views/account/delete.py
new file mode 100644
index 00000000..798b8a33
--- /dev/null
+++ b/pydis_site/apps/home/views/account/delete.py
@@ -0,0 +1,37 @@
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib.messages import ERROR, INFO, add_message
+from django.http import HttpRequest, HttpResponse
+from django.shortcuts import redirect, render
+from django.urls import reverse
+from django.views import View
+
+from pydis_site.apps.home.forms.account_deletion import AccountDeletionForm
+
+
+class DeleteView(LoginRequiredMixin, View):
+ """Account deletion view, for removing linked user accounts from the DB."""
+
+ def __init__(self, *args, **kwargs):
+ self.login_url = reverse("home")
+ super().__init__(*args, **kwargs)
+
+ def get(self, request: HttpRequest) -> HttpResponse:
+ """HTTP GET: Return the view template."""
+ return render(
+ request, "home/account/delete.html",
+ context={"form": AccountDeletionForm()}
+ )
+
+ def post(self, request: HttpRequest) -> HttpResponse:
+ """HTTP POST: Process the deletion, as requested by the user."""
+ form = AccountDeletionForm(request.POST)
+
+ if not form.is_valid() or request.user.username != form.cleaned_data["username"]:
+ add_message(request, ERROR, "Please enter your username exactly as shown.")
+
+ return redirect(reverse("account_delete"))
+
+ request.user.delete()
+ add_message(request, INFO, "Your account has been deleted.")
+
+ return redirect(reverse("home"))
diff --git a/pydis_site/apps/home/views/account/settings.py b/pydis_site/apps/home/views/account/settings.py
new file mode 100644
index 00000000..3a817dbc
--- /dev/null
+++ b/pydis_site/apps/home/views/account/settings.py
@@ -0,0 +1,59 @@
+from allauth.socialaccount.models import SocialAccount
+from allauth.socialaccount.providers import registry
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib.messages import ERROR, INFO, add_message
+from django.http import HttpRequest, HttpResponse
+from django.shortcuts import redirect, render
+from django.urls import reverse
+from django.views import View
+
+
+class SettingsView(LoginRequiredMixin, View):
+ """
+ Account settings view, for managing and deleting user accounts and connections.
+
+ This view actually renders a template with a bare modal, and is intended to be
+ inserted into another template using JavaScript.
+ """
+
+ def __init__(self, *args, **kwargs):
+ self.login_url = reverse("home")
+ super().__init__(*args, **kwargs)
+
+ def get(self, request: HttpRequest) -> HttpResponse:
+ """HTTP GET: Return the view template."""
+ context = {
+ "groups": request.user.groups.all(),
+
+ "discord": None,
+ "github": None,
+
+ "discord_provider": registry.provider_map.get("discord"),
+ "github_provider": registry.provider_map.get("github"),
+ }
+
+ for account in SocialAccount.objects.filter(user=request.user).all():
+ if account.provider == "discord":
+ context["discord"] = account
+
+ if account.provider == "github":
+ context["github"] = account
+
+ return render(request, "home/account/settings.html", context=context)
+
+ def post(self, request: HttpRequest) -> HttpResponse:
+ """HTTP POST: Process account disconnections."""
+ provider = request.POST["provider"]
+
+ if provider == "github":
+ try:
+ account = SocialAccount.objects.get(user=request.user, provider=provider)
+ except SocialAccount.DoesNotExist:
+ add_message(request, ERROR, "You do not have a GitHub account linked.")
+ else:
+ account.delete()
+ add_message(request, INFO, "The social account has been disconnected.")
+ else:
+ add_message(request, ERROR, f"Unknown provider: {provider}")
+
+ return redirect(reverse("home"))
diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py
index 4cf22594..3b5cd5ac 100644
--- a/pydis_site/apps/home/views/home.py
+++ b/pydis_site/apps/home/views/home.py
@@ -23,8 +23,8 @@ class HomeView(View):
"python-discord/bot",
"python-discord/snekbox",
"python-discord/seasonalbot",
+ "python-discord/metricity",
"python-discord/django-simple-bulma",
- "python-discord/django-crispy-bulma",
]
def _get_api_data(self) -> Dict[str, Dict[str, str]]:
@@ -61,7 +61,7 @@ class HomeView(View):
# Try to get new data from the API. If it fails, return the cached data.
try:
api_repositories = self._get_api_data()
- except TypeError:
+ except (TypeError, ConnectionError):
return RepositoryMetadata.objects.all()
database_repositories = []