38191-vm/core/views.py
2026-02-05 16:44:24 +00:00

133 lines
4.8 KiB
Python

from django.shortcuts import render, redirect, get_object_or_404
from django.views import View
from django.views.generic import ListView, CreateView, DetailView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.db.models import Q
from django.http import JsonResponse
from .models import Bookmark, Team, Extraction, BookmarkShare
from .tasks import process_bookmark
class BookmarkListView(LoginRequiredMixin, ListView):
model = Bookmark
template_name = 'core/index.html'
context_object_name = 'bookmarks'
paginate_by = 20
def get_queryset(self):
queryset = Bookmark.objects.filter(user=self.request.user).order_by('-created_at')
# Search filter
query = self.request.GET.get('q')
if query:
queryset = queryset.filter(
Q(title__icontains=query) |
Q(url__icontains=query) |
Q(notes__icontains=query) |
Q(extraction__content_text__icontains=query)
).distinct()
# Tag filter
tag = self.request.GET.get('tag')
if tag:
queryset = queryset.filter(tags__name__in=[tag])
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Add all tags used by the user for a sidebar or filter list
from taggit.models import Tag
context['all_tags'] = Tag.objects.filter(bookmark__user=self.request.user).distinct()
context['teams'] = self.request.user.teams.all()
return context
class BookmarkCreateView(LoginRequiredMixin, CreateView):
model = Bookmark
fields = ['url', 'title', 'notes', 'is_favorite']
template_name = 'core/bookmark_form.html'
success_url = reverse_lazy('home')
def form_valid(self, form):
form.instance.user = self.request.user
response = super().form_valid(form)
# Handle tags if provided in a separate field or as a comma-separated string
# For simplicity, we'll assume the model's TaggableManager handles it if added to fields,
# but here we might need to handle it manually if we use a custom field.
# Let's add 'tags' to fields in the actual form.
tags = self.request.POST.get('tags_input')
if tags:
form.instance.tags.add(*[t.strip() for t in tags.split(',')])
process_bookmark.delay(self.object.id)
return response
class BookmarkUpdateView(LoginRequiredMixin, UpdateView):
model = Bookmark
fields = ['url', 'title', 'notes', 'is_favorite']
template_name = 'core/bookmark_form.html'
success_url = reverse_lazy('home')
def get_queryset(self):
return Bookmark.objects.filter(user=self.request.user)
class BookmarkDeleteView(LoginRequiredMixin, DeleteView):
model = Bookmark
success_url = reverse_lazy('home')
def get_queryset(self):
return Bookmark.objects.filter(user=self.request.user)
class BookmarkDetailView(LoginRequiredMixin, DetailView):
model = Bookmark
template_name = 'core/bookmark_detail.html'
context_object_name = 'bookmark'
def get_queryset(self):
# Allow viewing if it's the user's bookmark OR shared with one of their teams
user_teams = self.request.user.teams.all()
return Bookmark.objects.filter(
Q(user=self.request.user) |
Q(shares__team__in=user_teams)
).distinct()
class TeamListView(LoginRequiredMixin, ListView):
model = Team
template_name = 'core/team_list.html'
context_object_name = 'teams'
def get_queryset(self):
return self.request.user.teams.all()
class TeamDetailView(LoginRequiredMixin, DetailView):
model = Team
template_name = 'core/team_detail.html'
context_object_name = 'team'
def get_queryset(self):
return self.request.user.teams.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Get bookmarks shared with this team
context['shared_bookmarks'] = Bookmark.objects.filter(shares__team=self.object).order_by('-shares__shared_at')
return context
class BookmarkShareToggleView(LoginRequiredMixin, View):
def post(self, request, pk, team_id):
bookmark = get_object_or_404(Bookmark, pk=pk, user=request.user)
team = get_object_or_404(Team, pk=team_id, members=request.user)
share, created = BookmarkShare.objects.get_or_create(
bookmark=bookmark,
team=team,
defaults={'shared_by': request.user}
)
if not created:
share.delete()
shared = False
else:
shared = True
return JsonResponse({'shared': shared})