mirror of
https://github.com/lossless-group/perplexed-plugin.git
synced 2026-07-22 06:49:50 +00:00
feat(source-profile): handle google_books_url for book-type sources
For Sources/ entries the model identifies as books: 1. Template: if frontmatter already has google_books_url, treat as authoritative and use it as the primary "Where it lives" link. Otherwise, search Google Books and find the canonical URL. 2. Post-processor in directoryTemplateService: harvest the first books.google.com or google.com/books/edition URL from generated body and stamp it to frontmatter as google_books_url. Only stamps when frontmatter doesn't already carry the field — user-curated URLs are never overwritten. This makes the URL findable in body content immediately after a run, and self-canonicalizes into frontmatter so subsequent runs skip the search. Same pattern as cf_last_run / cf_last_run_model: frontmatter is the canonical home for canonical IDs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c73cab6410
commit
9af617f38c
2 changed files with 24 additions and 2 deletions
12
src/docs/templates/source-profile.md
vendored
12
src/docs/templates/source-profile.md
vendored
|
|
@ -54,6 +54,16 @@ # About this template
|
|||
|
||||
- Book → emphasize author, publisher, year, thesis, key chapters /
|
||||
arguments. The "Catalog" section lists chapters or major arguments.
|
||||
GOOGLE BOOKS RULE: If the frontmatter above contains a
|
||||
`google_books_url` field, treat that URL as authoritative and use
|
||||
it as the primary "Where it lives" link. If the frontmatter does
|
||||
NOT contain `google_books_url`, search Google Books for the book's
|
||||
title (and author, when ambiguous) and find the canonical URL —
|
||||
the URL takes the form `https://books.google.com/books?id=XXXX`
|
||||
or `https://www.google.com/books/edition/.../XXXX`. Include the
|
||||
canonical URL as a `[Google Books](url)` link in "Where it lives".
|
||||
A post-processor will harvest the URL into frontmatter so future
|
||||
runs skip the search.
|
||||
- Person → emphasize bio, affiliation, body of work. The "Catalog"
|
||||
section lists their books / papers / talks / signature ideas.
|
||||
- Influencer / YouTuber / podcaster → emphasize host, channel URL,
|
||||
|
|
@ -111,7 +121,7 @@ # Type and Format
|
|||
- Journal: publisher, peer-review status, open-access status.
|
||||
- Report: issuing org, frequency (annual / one-off), pages, where to download.
|
||||
- Event: cadence, in-person / virtual / hybrid, host org, founded year.
|
||||
- **Where it lives:** a single `[Homepage](url)`-style markdown link to the source's primary surface. Add a second link to a secondary surface if relevant (e.g., for a podcaster: their show feed AND their newsletter).
|
||||
- **Where it lives:** a `[Homepage](url)`-style markdown link to the source's primary surface. Add a secondary link if relevant (e.g., for a podcaster: their show feed AND their newsletter). For books specifically: include a `[Google Books](url)` link — use `google_books_url` from frontmatter if present, otherwise search Google Books for the canonical URL (form: `https://books.google.com/books?id=XXXX` or `https://www.google.com/books/edition/...`).
|
||||
|
||||
# The People Behind It
|
||||
|
||||
|
|
|
|||
|
|
@ -570,13 +570,25 @@ export async function applyTemplate(
|
|||
const finalContent = `${initialContent}${cleanedStreamed}\n${fallbackImagesSection}${sourcesFooter}`;
|
||||
await app.vault.modify(target, finalContent);
|
||||
|
||||
// Harvest a Google Books URL from generated body if the model surfaced
|
||||
// one — books are the only source type with a universal canonical-URL
|
||||
// system worth stamping back into frontmatter. First match wins; we
|
||||
// only stamp when frontmatter doesn't already carry the field so a
|
||||
// user-curated URL is never overwritten.
|
||||
const googleBooksRe = /https:\/\/(?:www\.)?(?:books\.google\.com\/books\?id=[\w-]+|google\.com\/books\/edition\/[^\s)]+)/;
|
||||
const googleBooksMatch = cleanedStreamed.match(googleBooksRe);
|
||||
const harvestedGoogleBooksUrl = googleBooksMatch?.[0];
|
||||
|
||||
// Stamp run metadata in the target's frontmatter so files can be
|
||||
// queried for staleness ("which Tooling/ entries were last refreshed
|
||||
// before <date>?"). Uses fileManager.processFrontMatter so other
|
||||
// frontmatter keys remain byte-identical apart from these two.
|
||||
// frontmatter keys remain byte-identical apart from these stamps.
|
||||
await app.fileManager.processFrontMatter(target, (fm: Record<string, unknown>) => {
|
||||
fm['cf_last_run'] = runTimestamp;
|
||||
fm['cf_last_run_model'] = runModelLabel;
|
||||
if (harvestedGoogleBooksUrl && !fm['google_books_url']) {
|
||||
fm['google_books_url'] = harvestedGoogleBooksUrl;
|
||||
}
|
||||
});
|
||||
|
||||
if (!quiet) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue