Skip to content

Commit

Permalink
Merge pull request #1310 from lpsinger/ads
Browse files Browse the repository at this point in the history
Link Circulars to ADS entries
  • Loading branch information
dakota002 authored Aug 30, 2023
2 parents 839b93c + 0530c54 commit a455c31
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 4 deletions.
5 changes: 5 additions & 0 deletions app.arc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ circulars
support
src build/email-incoming/support

@scheduled
ads
rate 1 day
src build/scheduled/ads

@tables-streams
circulars
src build/table-streams/circulars
Expand Down
30 changes: 27 additions & 3 deletions app/routes/circulars.$circularId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
} from '@remix-run/node'
import { json } from '@remix-run/node'
import { Link, useLoaderData } from '@remix-run/react'
import { ButtonGroup, Grid, Icon } from '@trussworks/react-uswds'
import { Button, ButtonGroup, Grid, Icon } from '@trussworks/react-uswds'

import { formatDateISO } from './circulars/circulars.lib'
import { get } from './circulars/circulars.server'
Expand Down Expand Up @@ -51,8 +51,15 @@ const submittedHowMap = {
}

export default function () {
const { circularId, subject, submitter, createdOn, body, submittedHow } =
useLoaderData<typeof loader>()
const {
circularId,
subject,
submitter,
createdOn,
body,
submittedHow,
bibcode,
} = useLoaderData<typeof loader>()
const searchString = useSearchString()
return (
<>
Expand Down Expand Up @@ -82,6 +89,23 @@ export default function () {
JSON
</Link>
</ButtonGroup>
{bibcode ? (
<Link
to={`https://ui.adsabs.harvard.edu/abs/${bibcode}`}
className="usa-button usa-button--outline"
>
Cite (ADS)
</Link>
) : (
<Button
type="button"
disabled
outline
title="The ADS entry for this Circular is not yet available. ADS entries are updated daily. Please check back later."
>
Cite (ADS)
</Button>
)}
</ButtonGroup>
<h1>GCN Circular {circularId}</h1>
<Grid row>
Expand Down
1 change: 1 addition & 0 deletions app/routes/circulars/circulars.lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface Circular extends CircularMetadata {
body: string
submitter: string
submittedHow?: SubmittedHow
bibcode?: string
}

type SubjectMatcher = [RegExp, (match: RegExpMatchArray) => string]
Expand Down
2 changes: 2 additions & 0 deletions app/routes/docs.circulars.archive.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Upon successful submission and distribution, a GCN Circulars is assigned a numbe

The [SAO/NASA Astrophysics Data System (ADS)](https://ui.adsabs.harvard.edu) ingests and indexes all GCN Circulars. You can use ADS to get bibliographic records for GCN Circulars to cite them in a publication.

When you are viewing a GCN Circular in the archive, you can click the "Cite (ADS)" button to go to the ADS entry for that Circular. Note that ADS entries are updated once a day, so the button may be disabled for GCN Circulars that were posted less than 24 hours ago.

## GCN Viewer

The [GCN Viewer](https://heasarc.gsfc.nasa.gov/wsgi-scripts/tach/gcn_v2/tach.wsgi/) also automatically ingests and parses GCN Circulars, sorting them by astronomical event, and associates them with their [GCN Notices](/notices).
Expand Down
8 changes: 8 additions & 0 deletions app/routes/docs.contributing.configuration/route.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ _All_ environment variables are _optional in local development_. _All_ environme
<Description>Zendesk API token and user email address</Description>
<Default>Zendesk API disabled</Default>
</tr>
<tr>
<Key>`ADS_TOKEN`</Key>
<Description>
[Astrophysics Data System (ADS)](https://ui.adsabs.harvard.edu) API
token
</Description>
<Default>ADS disabled</Default>
</tr>
<tr>
<Key>`GCN_FEATURES`</Key>
<Description>
Expand Down
71 changes: 71 additions & 0 deletions app/scheduled/ads/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*!
* Copyright © 2023 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
import { tables } from '@architect/functions'
import { ConditionalCheckFailedException } from '@aws-sdk/client-dynamodb'

import { getEnvOrDie } from '~/lib/env.server'

const adsToken = getEnvOrDie('ADS_TOKEN')

async function* getAdsEntries() {
const url = new URL('https://api.adsabs.harvard.edu/v1/search/query')
url.searchParams.set('q', 'bibstem:GCN')
url.searchParams.set('fl', 'bibcode,volume')
url.searchParams.set('rows', '2000')
let start = 0
let length

let items: { bibcode: string; volume: string }[]
do {
const result = await fetch(url, {
headers: { Authorization: `Bearer ${adsToken}` },
})
if (!result.ok)
throw new Error(`${url.toString()} returned HTTP status ${result.status}`)

items = (await result.json()).response.docs
length = items.length
start += length
url.searchParams.set('start', start.toString())

yield items.map(({ bibcode, volume }) => ({
bibcode,
circularId: Number(volume.replace('a', '.5')),
}))
} while (length)
}

// FIXME: must use module.exports here for OpenTelemetry shim to work correctly.
// See https://dev.to/heymarkkop/how-to-solve-cannot-redefine-property-handler-on-aws-lambda-3j67
module.exports.handler = async () => {
const db = await tables()
for await (const entries of getAdsEntries()) {
await Promise.all(
entries.map(async ({ bibcode, circularId }) => {
try {
await db.circulars.update({
ConditionExpression: 'attribute_exists(circularId)',
ExpressionAttributeValues: {
':bibcode': bibcode,
},
Key: { circularId },
UpdateExpression: 'set bibcode = :bibcode',
})
} catch (e) {
if (e instanceof ConditionalCheckFailedException) {
console.error(
`Attempted to update Circular ${circularId}, which does not exist in DynamoDB`
)
} else {
throw e
}
}
})
)
}
}
2 changes: 2 additions & 0 deletions build/scheduled/ads/config.arc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@aws
timeout 900
2 changes: 1 addition & 1 deletion esbuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { glob } from 'glob'
const args = process.argv.slice(2)
const dev = args.includes('--dev')
const entryPoints = await glob(
'./app/{email-incoming,table-streams}/*/index.ts'
'./app/{email-incoming,scheduled,table-streams}/*/index.ts'
)

/**
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@architect/plugin-storage-private": "^1.0.1",
"@architect/utils": "^3.1.9",
"@aws-sdk/client-cognito-identity-provider": "^3.319.0",
"@aws-sdk/client-dynamodb": "^3.319.0",
"@aws-sdk/client-s3": "^3.319.0",
"@aws-sdk/client-sesv2": "^3.319.0",
"@aws-sdk/lib-dynamodb": "^3.319.0",
Expand Down

0 comments on commit a455c31

Please sign in to comment.