from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpRequest, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse from bookmarks.models import BookmarkBundle, BookmarkBundleForm, BookmarkSearch from bookmarks.queries import parse_query_string from bookmarks.services import bundles from bookmarks.views import access from bookmarks.views.contexts import ActiveBookmarkListContext @login_required def index(request: HttpRequest): bundles = BookmarkBundle.objects.filter(owner=request.user).order_by("order") context = {"bundles": bundles} return render(request, "bundles/index.html", context) @login_required def action(request: HttpRequest): if "remove_bundle" in request.POST: remove_bundle_id = request.POST.get("remove_bundle") bundle = access.bundle_write(request, remove_bundle_id) bundle_name = bundle.name bundles.delete_bundle(bundle) messages.success(request, f"Bundle '{bundle_name}' removed successfully.") elif "move_bundle" in request.POST: bundle_id = request.POST.get("move_bundle") bundle_to_move = access.bundle_write(request, bundle_id) move_position = int(request.POST.get("move_position")) bundles.move_bundle(bundle_to_move, move_position) return HttpResponseRedirect(reverse("linkding:bundles.index")) def _handle_edit(request: HttpRequest, template: str, bundle: BookmarkBundle = None): form_data = request.POST if request.method == "POST" else None initial_data = {} if bundle is None and request.method == "GET": query_param = request.GET.get("q") if query_param: parsed = parse_query_string(query_param) if parsed["search_terms"]: initial_data["search"] = " ".join(parsed["search_terms"]) if parsed["tag_names"]: initial_data["all_tags"] = " ".join(parsed["tag_names"]) form = BookmarkBundleForm(form_data, instance=bundle, initial=initial_data) if request.method == "POST": if form.is_valid(): instance = form.save(commit=False) if bundle is None: instance.order = None bundles.create_bundle(instance, request.user) else: instance.save() messages.success(request, "Bundle saved successfully.") return HttpResponseRedirect(reverse("linkding:bundles.index")) status = 422 if request.method == "POST" and not form.is_valid() else 200 bookmark_list = _get_bookmark_list_preview(request, bundle, initial_data) context = { "form": form, "bundle": bundle, "bookmark_list": bookmark_list, } return render(request, template, context, status=status) @login_required def new(request: HttpRequest): return _handle_edit(request, "bundles/new.html") @login_required def edit(request: HttpRequest, bundle_id: int): bundle = access.bundle_write(request, bundle_id) return _handle_edit(request, "bundles/edit.html", bundle) @login_required def preview(request: HttpRequest): bookmark_list = _get_bookmark_list_preview(request) context = {"bookmark_list": bookmark_list} return render(request, "bundles/preview.html", context) def _get_bookmark_list_preview( request: HttpRequest, bundle: BookmarkBundle | None = None, initial_data: dict = None, ): if request.method == "GET" and bundle: preview_bundle = bundle else: form_data = ( request.POST.copy() if request.method == "POST" else request.GET.copy() ) if initial_data: for key, value in initial_data.items(): form_data[key] = value form_data["name"] = "Preview Bundle" # Set dummy name for form validation form = BookmarkBundleForm(form_data) preview_bundle = form.save(commit=False) search = BookmarkSearch(bundle=preview_bundle) bookmark_list = ActiveBookmarkListContext(request, search) bookmark_list.is_preview = True return bookmark_list