summaryrefslogtreecommitdiffstats
path: root/activities/views
diff options
context:
space:
mode:
authorMichael Manfre2022-11-28 23:41:36 -0500
committerGitHub2022-11-28 21:41:36 -0700
commitfb8f2d10984bcfa2585dc272b4c85d285b722792 (patch)
treefa9616f745c7e9e4b5cc5d1ca82d61512ee64f01 /activities/views
parent7f838433edde6a03d1b7f71da269f9756a3f91e9 (diff)
downloadtakahe-fb8f2d10984bcfa2585dc272b4c85d285b722792.tar.gz
takahe-fb8f2d10984bcfa2585dc272b4c85d285b722792.tar.bz2
takahe-fb8f2d10984bcfa2585dc272b4c85d285b722792.zip
Hashtags
Diffstat (limited to 'activities/views')
-rw-r--r--activities/views/admin/__init__.py0
-rw-r--r--activities/views/explore.py26
-rw-r--r--activities/views/search.py43
-rw-r--r--activities/views/timelines.py45
4 files changed, 98 insertions, 16 deletions
diff --git a/activities/views/admin/__init__.py b/activities/views/admin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/activities/views/admin/__init__.py
diff --git a/activities/views/explore.py b/activities/views/explore.py
new file mode 100644
index 0000000..ddb1e6c
--- /dev/null
+++ b/activities/views/explore.py
@@ -0,0 +1,26 @@
+from django.views.generic import ListView
+
+from activities.models import Hashtag
+
+
+class ExploreTag(ListView):
+
+ template_name = "activities/explore_tag.html"
+ extra_context = {
+ "current_page": "explore",
+ "allows_refresh": True,
+ }
+ paginate_by = 20
+
+ def get_queryset(self):
+ return (
+ Hashtag.objects.public()
+ .filter(
+ stats__total__gt=0,
+ )
+ .order_by("-stats__total")
+ )[:20]
+
+
+class Explore(ExploreTag):
+ pass
diff --git a/activities/views/search.py b/activities/views/search.py
index b175052..4719f64 100644
--- a/activities/views/search.py
+++ b/activities/views/search.py
@@ -1,6 +1,9 @@
+from typing import Set
+
from django import forms
from django.views.generic import FormView
+from activities.models import Hashtag
from users.models import Domain, Identity
@@ -9,13 +12,13 @@ class Search(FormView):
template_name = "activities/search.html"
class form_class(forms.Form):
- query = forms.CharField(help_text="Search for a user by @username@domain")
-
- def form_valid(self, form):
- query = form.cleaned_data["query"].lstrip("@").lower()
- results = {"identities": set()}
- # Search identities
+ query = forms.CharField(
+ help_text="Search for a user by @username@domain or hashtag by #tagname"
+ )
+ def search_identities(self, query: str):
+ query = query.lstrip("@")
+ results: Set[Identity] = set()
if "@" in query:
username, domain = query.split("@", 1)
@@ -35,13 +38,35 @@ class Search(FormView):
)
identity = None
if identity:
- results["identities"].add(identity)
+ results.add(identity)
else:
for identity in Identity.objects.filter(username=query)[:20]:
- results["identities"].add(identity)
+ results.add(identity)
for identity in Identity.objects.filter(username__startswith=query)[:20]:
- results["identities"].add(identity)
+ results.add(identity)
+ return results
+
+ def search_hashtags(self, query: str):
+ results: Set[Hashtag] = set()
+
+ if "@" in query:
+ return results
+
+ query = query.lstrip("#")
+ for hashtag in Hashtag.objects.public().hashtag_or_alias(query)[:10]:
+ results.add(hashtag)
+ for hashtag in Hashtag.objects.public().filter(hashtag__startswith=query)[:10]:
+ results.add(hashtag)
+ return results
+
+ def form_valid(self, form):
+ query = form.cleaned_data["query"].lower()
+ results = {
+ "identities": self.search_identities(query),
+ "hashtags": self.search_hashtags(query),
+ }
+
# Render results
context = self.get_context_data(form=form)
context["results"] = results
diff --git a/activities/views/timelines.py b/activities/views/timelines.py
index 4f2a515..ffe329c 100644
--- a/activities/views/timelines.py
+++ b/activities/views/timelines.py
@@ -1,10 +1,10 @@
from django import forms
-from django.shortcuts import redirect
+from django.shortcuts import get_object_or_404, redirect
from django.template.defaultfilters import linebreaks_filter
from django.utils.decorators import method_decorator
from django.views.generic import FormView, ListView
-from activities.models import Post, PostInteraction, TimelineEvent
+from activities.models import Hashtag, Post, PostInteraction, TimelineEvent
from core.models import Config
from users.decorators import identity_required
@@ -61,6 +61,41 @@ class Home(FormView):
return redirect(".")
+class Tag(ListView):
+
+ template_name = "activities/tag.html"
+ extra_context = {
+ "current_page": "tag",
+ "allows_refresh": True,
+ }
+ paginate_by = 50
+
+ def get(self, request, hashtag, *args, **kwargs):
+ tag = hashtag.lower().lstrip("#")
+ if hashtag != tag:
+ # SEO sanitize
+ return redirect(f"/tags/{tag}/", permanent=True)
+ self.hashtag = get_object_or_404(Hashtag.objects.public(), hashtag=tag)
+ return super().get(request, *args, **kwargs)
+
+ def get_queryset(self):
+ return (
+ Post.objects.local_public()
+ .tagged_with(self.hashtag)
+ .select_related("author")
+ .prefetch_related("attachments")
+ .order_by("-created")[:50]
+ )
+
+ def get_context_data(self):
+ context = super().get_context_data()
+ context["hashtag"] = self.hashtag
+ context["interactions"] = PostInteraction.get_post_interactions(
+ context["page_obj"], self.request.identity
+ )
+ return context
+
+
class Local(ListView):
template_name = "activities/local.html"
@@ -72,11 +107,7 @@ class Local(ListView):
def get_queryset(self):
return (
- Post.objects.filter(
- visibility=Post.Visibilities.public,
- author__local=True,
- in_reply_to__isnull=True,
- )
+ Post.objects.local_public()
.select_related("author")
.prefetch_related("attachments")
.order_by("-created")[:50]