Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions functions/src/events/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,23 @@ export const HearingContent = BaseEventContent.extend({
export type HearingListItem = Static<typeof HearingListItem>
export const HearingListItem = Record({ EventId: Number })

export type Video = Static<typeof Video>
export const Video = Record({
url: String,
title: String,
transcriptionId: String
})

export type Hearing = Static<typeof Hearing>
export const Hearing = BaseEvent.extend({
type: L("hearing"),
content: HearingContent,
videoURL: Optional(String),
videoTranscriptionId: Optional(String),
videoFetchedAt: Optional(InstanceOf(Timestamp)),
transcriptionIds: Optional(Array(String)),
videos: Optional(Array(Video)),
videosFetchedAt: Optional(InstanceOf(Timestamp)),
committeeChairs: Optional(Array(String))
})

Expand Down
10 changes: 8 additions & 2 deletions functions/src/hearings/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ export const {
},
convert: data => {
const hearing = Hearing.check(data)
const { content, startsAt: startsAtTimestamp, id, videoURL } = hearing
const {
content,
startsAt: startsAtTimestamp,
id,
videoURL,
videos
} = hearing
const startsAt = startsAtTimestamp.toMillis()
const schedule = DateTime.fromMillis(startsAt, { zone: timeZone })

Expand Down Expand Up @@ -115,7 +121,7 @@ export const {
bill => bill.slug || `${courtNumber}/${bill.number}`
),
court: courtNumber,
hasVideo: Boolean(videoURL)
hasVideo: Boolean(videoURL || videos?.length)
}
}
})
17 changes: 17 additions & 0 deletions scripts/firebase-admin/cleanupHearingVideoFormat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FieldValue } from "../../functions/src/firebase"
import { reformatFactory } from "./updateHearingVideoFormat"
import { Script } from "./types"

function getVideoFormatCleanup(data: FirebaseFirestore.DocumentData): any {
if (!("videoURL" in data)) {
return null
}

return {
videoTranscriptionId: FieldValue.delete(),
videoFetchedAt: FieldValue.delete(),
videoURL: FieldValue.delete()
}
}

export const script: Script = reformatFactory(getVideoFormatCleanup)
98 changes: 98 additions & 0 deletions scripts/firebase-admin/updateHearingVideoFormat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Record, String } from "runtypes"
import { Script } from "./types"

const Args = Record({
hearingId: String.optional()
})

export function reformatFactory(
fn: (data: FirebaseFirestore.DocumentData) => any
) {
return async ({
db,
args
}: {
db: FirebaseFirestore.Firestore
args: any
}) => {
const { hearingId } = Args.check(args)

// Process a single event by eventId
if (hearingId) {
const snapshot = await db
.collection("events")
.where("type", "==", "hearing")
.where("id", "==", hearingId)
.get()

if (snapshot.empty || snapshot.docs.length !== 1) {
throw new Error(
`The number of documents matching the event id ${hearingId} must be exactly one`
)
}

const doc = snapshot.docs[0]
const modify = fn(doc.data())
if (modify) {
await doc.ref.update(modify)
}
} else {
const snapshot = await db
.collection("events")
.where("type", "==", "hearing")
.get()

if (snapshot.empty) {
throw new Error("Hearing backfill failed; no documents were found")
}

let bulkWriter = db.bulkWriter()

for (const doc of snapshot.docs) {
console.log(doc.data().id)
const modify = fn(doc.data())
if (modify) {
bulkWriter.update(doc.ref, modify)
}
}
await bulkWriter.close()
}

console.log("Video backfill complete")
}
}

function getVideoFormatUpdate(data: FirebaseFirestore.DocumentData): any {
if ("videos" in data || !("videoURL" in data)) {
return null
}

const url = data.videoURL
const fetchedAt = data.videoFetchedAt
const transcriptionId = data.videoTranscriptionId

if (!url || !fetchedAt || !transcriptionId) {
throw new Error(
`In the data for ${data.id}, it is expected that if videoURL exists videoFetchedAt and videoTranscriptionId also exist`
)
}

const transcriptionIds = [transcriptionId]

const videos = [
{
// Default; not shown
title: data.id,
url,
transcriptionId
}
]

return {
videos,
transcriptionIds,
videosFetchedAt: fetchedAt
}
}

export const script: Script = reformatFactory(getVideoFormatUpdate)
Loading