Skip to content

Commit

Permalink
feat(route): inspirehep (#16261)
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyRL authored Jul 25, 2024
1 parent b7b64b2 commit 46ba2a8
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 0 deletions.
46 changes: 46 additions & 0 deletions lib/routes/inspirehep/author.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import { AuthorResponse, LiteratureResponse } from './types';
import cache from '@/utils/cache';

import { baseUrl, parseLiterature } from './utils';

export const route: Route = {
path: '/authors/:id',
example: '/inspirehep/authors/1696909',
parameters: { id: 'Author ID' },
name: 'Author Search',
maintainers: ['TonyRL'],
radar: [
{
source: ['inspirehep.net/authors/:id'],
},
],
handler,
};

export const getAuthorById = (id: string) => cache.tryGet(`inspirehep:author:${id}`, () => ofetch<AuthorResponse>(`${baseUrl}/api/authors/${id}`));

async function handler(ctx) {
const id = ctx.req.param('id');
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25;

const authorInfo = (await getAuthorById(id)) as AuthorResponse;
const response = await ofetch<LiteratureResponse>(`${baseUrl}/api/literature`, {
query: {
sort: 'mostrecent',
size: limit,
page: 1,
search_type: 'hep-author-publication',
author: authorInfo.metadata.facet_author_name,
},
});

const items = parseLiterature(response.hits.hits);

return {
title: `${authorInfo.metadata.name.preferred_name} - INSPIRE`,
link: `${baseUrl}/authors/${id}`,
item: items,
};
}
42 changes: 42 additions & 0 deletions lib/routes/inspirehep/literature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import { LiteratureResponse } from './types';

import { baseUrl, parseLiterature } from './utils';

export const route: Route = {
path: '/literature/:q',
example: '/inspirehep/literature/Physics',
parameters: { q: 'Search keyword' },
name: 'Literature Search',
maintainers: ['TonyRL'],
radar: [
{
source: ['inspirehep.net/literature'],
target: (_params, url) => `/inspirehep/literature/${new URL(url).searchParams.get('q')}`,
},
],
handler,
};

async function handler(ctx) {
const q = ctx.req.param('q');
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25;

const response = await ofetch<LiteratureResponse>(`${baseUrl}/api/literature`, {
query: {
sort: 'mostrecent',
size: limit,
page: 1,
q,
},
});

const items = parseLiterature(response.hits.hits);

return {
title: 'Literature Search - INSPIRE',
link: `${baseUrl}/literature?sort=mostrecent&size=${limit}&page=1&q=${q}`,
item: items,
};
}
7 changes: 7 additions & 0 deletions lib/routes/inspirehep/namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Namespace } from '@/types';

export const namespace: Namespace = {
name: 'INSPIRE',
url: 'inspirehep.net',
categories: ['journal'],
};
210 changes: 210 additions & 0 deletions lib/routes/inspirehep/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
interface Links {
self?: string;
next?: string;
bibtex: string;
'latex-eu': string;
'latex-us': string;
json: string;
cv: string;
citations: string;
}

interface Metadata {
number_of_authors: number;
date: string;
publication_info: {
year: number;
artid?: string;
journal_volume?: string;
journal_title?: string;
journal_issue?: string;
}[];
citation_count: number;
is_collection_hidden: boolean;
authors: {
uuid: string;
record: {
$ref: string;
};
full_name: string;
first_name: string;
ids: {
schema: string;
value: string;
}[];
last_name: string;
recid: number;
affiliations: {
value: string;
record: {
$ref: string;
};
curated_relation?: boolean;
}[];
raw_affiliations: {
value: string;
}[];
curated_relation?: boolean;
}[];
citation_count_without_self_citations: number;
titles: {
title: string;
source: string;
}[];
texkeys: string[];
imprints: {
date: string;
publisher?: string;
}[];
abstracts: {
value: string;
source: string;
}[];
document_type: string[];
control_number: number;
inspire_categories: {
term: string;
source?: string;
}[];
number_of_pages?: number;
keywords?: {
value: string;
source?: string;
schema?: string;
}[];
thesis_info?: {
institutions: {
name: string;
record: {
$ref: string;
};
curated_relation?: boolean;
}[];
degree_type: string;
date: string;
};
license?: {
url: string;
license: string;
imposing?: string;
}[];
persistent_identifiers?: {
value: string;
schema: string;
source: string;
}[];
supervisors?: {
uuid: string;
record: {
$ref: string;
};
full_name: string;
inspire_roles: string[];
}[];
isbns?: {
value: string;
medium?: string;
}[];
urls?: {
value: string;
description?: string;
}[];
dois?: {
value: string;
}[];
number_of_references?: number;
external_system_identifiers?: {
url_name: string;
url_link: string;
}[];
report_numbers?: {
value: string;
}[];
accelerator_experiments?: {
name: string;
record: {
$ref: string;
};
}[];
documents?: {
source: string;
key: string;
url: string;
fulltext: boolean;
hidden: boolean;
filename: string;
}[];
citation_pdf_urls?: string[];
fulltext_links?: {
description: string;
value: string;
}[];
}

interface Literature {
created: string;
metadata: Metadata;
links: Links;
updated: string;
id: string;
}

export interface AuthorResponse {
id: string;
uuid: string;
revision_id: number;
updated: string;
links: {
json: string;
};
metadata: {
can_edit: boolean;
orcid: string;
bai: string;
facet_author_name: string;
should_display_positions: boolean;
positions: {
institution: string;
current: boolean;
display_date: string;
record: {
$ref: string;
};
}[];
project_membership: {
name: string;
record: {
$ref: string;
};
current: boolean;
curated_relation: boolean;
}[];
ids: {
value: string;
schema: string;
}[];
name: {
value: string;
preferred_name: string;
};
stub: boolean;
status: string;
deleted: boolean;
control_number: number;
legacy_version: string;
legacy_creation_date: string;
};
created: string;
}

export interface LiteratureResponse {
hits: {
hits: Literature[];
total: number;
};
links: Links;
sort_options: {
value: string;
title: string;
}[];
}
15 changes: 15 additions & 0 deletions lib/routes/inspirehep/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LiteratureResponse } from './types';
import { parseDate } from '@/utils/parse-date';

export const baseUrl = 'https://inspirehep.net';

export const parseLiterature = (hits: LiteratureResponse['hits']['hits']) =>
hits.map((item) => ({
title: item.metadata.titles.map((t) => t.title).join(' '),
link: `${baseUrl}/literature/${item.id}`,
description: item.metadata.abstracts?.map((a) => `<span>${a.value}</span>`).join('<br>'),
pubDate: parseDate(item.created),
updated: parseDate(item.updated),
category: item.metadata.keywords?.map((k) => k.value),
author: item.metadata.authors.map((a) => `${a.first_name} ${a.last_name}${a.affiliations ? ` (${a.affiliations.map((aff) => aff.value).join(', ')})` : ''}`).join(', '),
}));

0 comments on commit 46ba2a8

Please sign in to comment.