mirror of
https://github.com/dergigi/boris.git
synced 2026-01-08 17:34:52 +01:00
- Add opengraphEnhancer service using fetch-opengraph library - Enhance ReadItems with proper titles, descriptions, and cover images - Update deriveLinksFromBookmarks to use async OpenGraph enhancement - Add caching and batching to avoid overwhelming external services - Improve bookmark card display with rich metadata from OpenGraph tags
74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { Bookmark } from '../types/bookmarks'
|
|
import { ReadItem } from '../services/readsService'
|
|
import { KINDS } from '../config/kinds'
|
|
import { fallbackTitleFromUrl } from './readItemMerge'
|
|
import { enhanceReadItemsWithOpenGraph } from '../services/opengraphEnhancer'
|
|
|
|
/**
|
|
* Derives ReadItems from bookmarks for external URLs:
|
|
* - Web bookmarks (kind:39701)
|
|
* - Any bookmark with http(s) URLs in content or urlReferences
|
|
*/
|
|
export async function deriveLinksFromBookmarks(bookmarks: Bookmark[]): Promise<ReadItem[]> {
|
|
const linksMap = new Map<string, ReadItem>()
|
|
|
|
const allBookmarks = bookmarks.flatMap(b => b.individualBookmarks || [])
|
|
|
|
for (const bookmark of allBookmarks) {
|
|
const urls: string[] = []
|
|
|
|
// Web bookmarks (kind:39701) - extract from 'd' tag
|
|
if (bookmark.kind === KINDS.WebBookmark) {
|
|
const dTag = bookmark.tags.find(t => t[0] === 'd')?.[1]
|
|
if (dTag) {
|
|
const url = dTag.startsWith('http') ? dTag : `https://${dTag}`
|
|
urls.push(url)
|
|
}
|
|
}
|
|
|
|
// Extract URLs from content if not already captured
|
|
if (bookmark.content) {
|
|
const urlRegex = /(https?:\/\/[^\s]+)/g
|
|
const matches = bookmark.content.match(urlRegex)
|
|
if (matches) {
|
|
urls.push(...matches)
|
|
}
|
|
}
|
|
|
|
// Extract metadata from tags (for web bookmarks and other types)
|
|
const title = bookmark.tags.find(t => t[0] === 'title')?.[1]
|
|
const summary = bookmark.tags.find(t => t[0] === 'summary')?.[1]
|
|
const image = bookmark.tags.find(t => t[0] === 'image')?.[1]
|
|
|
|
// Create ReadItem for each unique URL
|
|
for (const url of [...new Set(urls)]) {
|
|
if (!linksMap.has(url)) {
|
|
const item: ReadItem = {
|
|
id: url,
|
|
source: 'bookmark',
|
|
type: 'external',
|
|
url,
|
|
title: title || fallbackTitleFromUrl(url),
|
|
summary,
|
|
image,
|
|
readingProgress: 0,
|
|
readingTimestamp: bookmark.created_at ?? undefined
|
|
}
|
|
|
|
linksMap.set(url, item)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get initial items sorted by most recent bookmark activity
|
|
const initialItems = Array.from(linksMap.values()).sort((a, b) => {
|
|
const timeA = a.readingTimestamp || 0
|
|
const timeB = b.readingTimestamp || 0
|
|
return timeB - timeA
|
|
})
|
|
|
|
// Enhance with OpenGraph data
|
|
return await enhanceReadItemsWithOpenGraph(initialItems)
|
|
}
|
|
|