mirror of
				https://github.com/sissbruecker/linkding.git
				synced 2025-11-04 04:54:09 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			125 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import unicodedata
 | 
						|
from dataclasses import dataclass
 | 
						|
 | 
						|
from django.contrib.syndication.views import Feed
 | 
						|
from django.db.models import QuerySet, prefetch_related_objects
 | 
						|
from django.http import HttpRequest
 | 
						|
from django.urls import reverse
 | 
						|
 | 
						|
from bookmarks import queries
 | 
						|
from bookmarks.models import Bookmark, BookmarkSearch, FeedToken, UserProfile
 | 
						|
from bookmarks.views import access
 | 
						|
 | 
						|
 | 
						|
@dataclass
 | 
						|
class FeedContext:
 | 
						|
    request: HttpRequest
 | 
						|
    feed_token: FeedToken | None
 | 
						|
    query_set: QuerySet[Bookmark]
 | 
						|
 | 
						|
 | 
						|
def sanitize(text: str):
 | 
						|
    if not text:
 | 
						|
        return ""
 | 
						|
    # remove control characters
 | 
						|
    valid_chars = ["\n", "\r", "\t"]
 | 
						|
    return "".join(
 | 
						|
        ch for ch in text if ch in valid_chars or unicodedata.category(ch)[0] != "C"
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
class BaseBookmarksFeed(Feed):
 | 
						|
    def get_object(self, request, feed_key: str | None):
 | 
						|
        feed_token = FeedToken.objects.get(key__exact=feed_key) if feed_key else None
 | 
						|
        bundle = None
 | 
						|
        bundle_id = request.GET.get("bundle")
 | 
						|
        if bundle_id:
 | 
						|
            bundle = access.bundle_read(request, bundle_id)
 | 
						|
 | 
						|
        search = BookmarkSearch(
 | 
						|
            q=request.GET.get("q", ""),
 | 
						|
            unread=request.GET.get("unread", ""),
 | 
						|
            shared=request.GET.get("shared", ""),
 | 
						|
            bundle=bundle,
 | 
						|
        )
 | 
						|
        query_set = self.get_query_set(feed_token, search)
 | 
						|
        return FeedContext(request, feed_token, query_set)
 | 
						|
 | 
						|
    def get_query_set(self, feed_token: FeedToken, search: BookmarkSearch):
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    def items(self, context: FeedContext):
 | 
						|
        limit = context.request.GET.get("limit", 100)
 | 
						|
        if limit:
 | 
						|
            data = context.query_set[: int(limit)]
 | 
						|
        else:
 | 
						|
            data = list(context.query_set)
 | 
						|
        prefetch_related_objects(data, "tags")
 | 
						|
        return data
 | 
						|
 | 
						|
    def item_title(self, item: Bookmark):
 | 
						|
        return sanitize(item.resolved_title)
 | 
						|
 | 
						|
    def item_description(self, item: Bookmark):
 | 
						|
        return sanitize(item.resolved_description)
 | 
						|
 | 
						|
    def item_link(self, item: Bookmark):
 | 
						|
        return item.url
 | 
						|
 | 
						|
    def item_pubdate(self, item: Bookmark):
 | 
						|
        return item.date_added
 | 
						|
 | 
						|
    def item_categories(self, item: Bookmark):
 | 
						|
        return item.tag_names
 | 
						|
 | 
						|
 | 
						|
class AllBookmarksFeed(BaseBookmarksFeed):
 | 
						|
    title = "All bookmarks"
 | 
						|
    description = "All bookmarks"
 | 
						|
 | 
						|
    def get_query_set(self, feed_token: FeedToken, search: BookmarkSearch):
 | 
						|
        return queries.query_bookmarks(feed_token.user, feed_token.user.profile, search)
 | 
						|
 | 
						|
    def link(self, context: FeedContext):
 | 
						|
        return reverse("linkding:feeds.all", args=[context.feed_token.key])
 | 
						|
 | 
						|
 | 
						|
class UnreadBookmarksFeed(BaseBookmarksFeed):
 | 
						|
    title = "Unread bookmarks"
 | 
						|
    description = "All unread bookmarks"
 | 
						|
 | 
						|
    def get_query_set(self, feed_token: FeedToken, search: BookmarkSearch):
 | 
						|
        return queries.query_bookmarks(
 | 
						|
            feed_token.user, feed_token.user.profile, search
 | 
						|
        ).filter(unread=True)
 | 
						|
 | 
						|
    def link(self, context: FeedContext):
 | 
						|
        return reverse("linkding:feeds.unread", args=[context.feed_token.key])
 | 
						|
 | 
						|
 | 
						|
class SharedBookmarksFeed(BaseBookmarksFeed):
 | 
						|
    title = "Shared bookmarks"
 | 
						|
    description = "All shared bookmarks"
 | 
						|
 | 
						|
    def get_query_set(self, feed_token: FeedToken, search: BookmarkSearch):
 | 
						|
        return queries.query_shared_bookmarks(
 | 
						|
            None, feed_token.user.profile, search, False
 | 
						|
        )
 | 
						|
 | 
						|
    def link(self, context: FeedContext):
 | 
						|
        return reverse("linkding:feeds.shared", args=[context.feed_token.key])
 | 
						|
 | 
						|
 | 
						|
class PublicSharedBookmarksFeed(BaseBookmarksFeed):
 | 
						|
    title = "Public shared bookmarks"
 | 
						|
    description = "All public shared bookmarks"
 | 
						|
 | 
						|
    def get_object(self, request):
 | 
						|
        return super().get_object(request, None)
 | 
						|
 | 
						|
    def get_query_set(self, feed_token: FeedToken, search: BookmarkSearch):
 | 
						|
        return queries.query_shared_bookmarks(None, UserProfile(), search, True)
 | 
						|
 | 
						|
    def link(self, context: FeedContext):
 | 
						|
        return reverse("linkding:feeds.public_shared")
 |