Skip to content

Commit

Permalink
feat(author): bake author gdocs
Browse files Browse the repository at this point in the history
  • Loading branch information
mlbrgl committed Mar 12, 2024
1 parent a09413d commit a5cc349
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 10 deletions.
66 changes: 63 additions & 3 deletions baker/SiteBaker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ import {
} from "../db/model/Variable.js"
import { Knex } from "knex"
import { getBakePath } from "@ourworldindata/components"
import { GdocAuthor } from "../db/model/Gdoc/GdocAuthor.js"

type PrefetchedAttachments = {
linkedDocuments: Record<string, OwidGdocMinimalPostInterface>
Expand Down Expand Up @@ -137,6 +138,7 @@ const nonWordpressSteps = [
"gdriveImages",
"dods",
"dataInsights",
"authors",
] as const

const otherSteps = ["removeDeletedPosts"] as const
Expand Down Expand Up @@ -302,7 +304,7 @@ export class SiteBaker {
picks?: [string[], string[], string[], string[]]
): Promise<PrefetchedAttachments> {
if (!this._prefetchedAttachmentsCache) {
const publishedGdocs = await GdocPost.getPublishedGdocs().then(
const publishedGdocs = await GdocPost.getPublishedGdocPosts().then(
(fullGdocs) => fullGdocs.map(fullGdocToMinimalGdoc)
)
const publishedGdocsDictionary = keyBy(publishedGdocs, "id")
Expand Down Expand Up @@ -441,7 +443,7 @@ export class SiteBaker {
postSlugs.push(post.slug)
}

const gdocPosts = await GdocPost.getPublishedGdocs()
const gdocPosts = await GdocPost.getPublishedGdocPosts()

for (const post of gdocPosts) {
postSlugs.push(post.slug)
Expand Down Expand Up @@ -483,7 +485,7 @@ export class SiteBaker {
async bakeGDocPosts(slugs?: string[]) {
await db.getConnection()
if (!this.bakeSteps.has("gdocPosts")) return
const publishedGdocs = await GdocPost.getPublishedGdocs()
const publishedGdocs = await GdocPost.getPublishedGdocPosts()

const gdocsToBake =
slugs !== undefined
Expand Down Expand Up @@ -765,6 +767,63 @@ export class SiteBaker {
await this.stageWrite(outPath, html)
}
}

private async bakeAuthors() {
if (!this.bakeSteps.has("authors")) return

const publishedAuthors = await GdocAuthor.getPublishedAuthors()

for (const publishedAuthor of publishedAuthors) {
const attachments = await this.getPrefetchedGdocAttachments([
publishedAuthor.linkedDocumentIds,
publishedAuthor.linkedImageFilenames,
publishedAuthor.linkedChartSlugs.grapher,
publishedAuthor.linkedChartSlugs.explorer,
])

// We don't need these to be attached to the gdoc in the current
// state of author pages. We'll keep them here as documentation
// of intent, until we need them.
// publishedAuthor.linkedCharts = {
// ...attachments.linkedCharts.graphers,
// ...attachments.linkedCharts.explorers,
// }

// Attach documents metadata linked to in the "featured work" section
publishedAuthor.linkedDocuments = attachments.linkedDocuments

// Attach image metadata for the profile picture and the "featured work" images
publishedAuthor.imageMetadata = attachments.imageMetadata

// Attach image metadata for the “latest work" images
await publishedAuthor.loadLatestWorkImages()

await publishedAuthor.validate()
if (
publishedAuthor.errors.filter(
(e) => e.type === OwidGdocErrorMessageType.Error
).length
) {
await logErrorAndMaybeSendToBugsnag(
`Error(s) baking "${
publishedAuthor.slug
}" :\n ${publishedAuthor.errors
.map((error) => error.message)
.join("\n ")}`
)
}
try {
await this.bakeOwidGdoc(publishedAuthor)
} catch (e) {
logErrorAndMaybeSendToBugsnag(
`Error baking author with id "${publishedAuthor.id}" and slug "${publishedAuthor.slug}": ${e}`
)
}
}

this.progressBar.tick({ name: "✅ baked author pages" })
}

// Pages that are expected by google scholar for indexing
private async bakeGoogleScholar() {
if (!this.bakeSteps.has("googleScholar")) return
Expand Down Expand Up @@ -927,6 +986,7 @@ export class SiteBaker {
await this.validateGrapherDodReferences()
await this.bakeGDocPosts()
await this.bakeDataInsights()
await this.bakeAuthors()
await this.bakeDriveImages()
}

Expand Down
2 changes: 1 addition & 1 deletion baker/algolia/indexToAlgolia.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ function generateGdocRecords(
// Generate records for countries, WP posts (not including posts that have been succeeded by Gdocs equivalents), and Gdocs
const getPagesRecords = async (knex: Knex<any, any[]>) => {
const pageviews = await getAnalyticsPageviewsByUrlObj(knex)
const gdocs = await GdocPost.getPublishedGdocs()
const gdocs = await GdocPost.getPublishedGdocPosts()
const publishedGdocsBySlug = keyBy(gdocs, "slug")
// TODO: the knex instance should be handed down as a parameter
const slugsWithPublishedGdocsSuccessors =
Expand Down
2 changes: 1 addition & 1 deletion baker/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const makeSitemap = async (
undefined,
(postrow) => !alreadyPublishedViaGdocsSlugsSet.has(postrow.slug)
)
const gdocPosts = await GdocPost.getPublishedGdocs()
const gdocPosts = await GdocPost.getPublishedGdocPosts()

const publishedDataInsights = await db.getPublishedDataInsights(knex)
const dataInsightFeedPageCount = calculateDataInsightIndexPageCount(
Expand Down
21 changes: 19 additions & 2 deletions db/model/Gdoc/GdocAuthor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Entity, Column } from "typeorm"
import { Entity, Column, Raw } from "typeorm"
import {
OwidGdocErrorMessage,
OwidGdocAuthorInterface,
Expand All @@ -8,6 +8,7 @@ import {
OwidGdocErrorMessageType,
DbEnrichedLatestWork,
DEFAULT_GDOC_FEATURED_IMAGE,
OwidGdocType,
} from "@ourworldindata/utils"
import { GdocBase } from "./GdocBase.js"
import { htmlToEnrichedTextBlock } from "./htmlToEnriched.js"
Expand Down Expand Up @@ -35,7 +36,11 @@ export class GdocAuthor extends GdocBase implements OwidGdocAuthorInterface {
return blocks
}

_loadSubclassAttachments = async (): Promise<void> => {
_loadSubclassAttachments = (): Promise<void> => {
return this.loadLatestWorkImages()
}

loadLatestWorkImages = async (): Promise<void> => {
if (!this.content.title) return
const knex = db.knexInstance()

Expand Down Expand Up @@ -109,4 +114,16 @@ export class GdocAuthor extends GdocBase implements OwidGdocAuthorInterface {
}
return errors
}

static async getPublishedAuthors(): Promise<GdocAuthor[]> {
return GdocAuthor.find({
where: {
published: true,
content: Raw(
(content) =>
`${content}->"$.type" = '${OwidGdocType.Author}'`
),
},
})
}
}
4 changes: 2 additions & 2 deletions db/model/Gdoc/GdocPost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export class GdocPost extends GdocBase implements OwidGdocPostInterface {
return parseDetails(gdoc.content.details)
}

static async getPublishedGdocs(): Promise<GdocPost[]> {
static async getPublishedGdocPosts(): Promise<GdocPost[]> {
// #gdocsvalidation this cast means that we trust the admin code and
// workflow to provide published articles that have all the required content
// fields (see #gdocsvalidationclient and pending #gdocsvalidationserver).
Expand Down Expand Up @@ -246,7 +246,7 @@ export class GdocPost extends GdocBase implements OwidGdocPostInterface {
/**
* Excludes published listed Gdocs with a publication date in the future
*/
static async getListedGdocs(): Promise<GdocPost[]> {
static async getListedGdocPosts(): Promise<GdocPost[]> {
return GdocPost.findBy({
published: true,
publicationContext: OwidGdocPublicationContext.listed,
Expand Down
2 changes: 1 addition & 1 deletion db/model/Post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ const selectHomepagePosts: FilterFnPostRestApi = (post) =>
export const getBlogIndex = memoize(
async (knex: Knex<any, any[]>): Promise<IndexPost[]> => {
await db.getConnection() // side effect: ensure connection is established
const gdocPosts = await GdocPost.getListedGdocs()
const gdocPosts = await GdocPost.getListedGdocPosts()
const wpPosts = await Promise.all(
await getPostsFromSnapshots(
knex,
Expand Down

0 comments on commit a5cc349

Please sign in to comment.