Skip to content

Commit

Permalink
feat(API): use tree endpoint to build TOC, use page ID's over paths
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanaturner committed May 12, 2024
1 parent 10321d9 commit 4598503
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 11 deletions.
15 changes: 7 additions & 8 deletions API/endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,17 @@ async function handler(request, response) {
}
} else if (url.startsWith('/getTOC/')) {
if (request.method === 'GET') {
let start = performance.now();
response.writeHead(200, {'Content-Type': 'application/json'});
let resourceURL = url.split('/getTOC/')[1];
resourceURL.replace('%3A', ':');
let pages = await LibreTexts.getSubpages(resourceURL, 'LibreBot', { flat: false });
let end = performance.now();
const start = performance.now();
response.writeHead(200, { 'Content-Type': 'application/json' });
const resourceURL = url.split('/getTOC/')[1];
const toc = await LibreTexts.getTOC(resourceURL, 'LibreBot');
const end = performance.now();
response.end(JSON.stringify({
time: `${end - start} ms`,
toc: pages
toc,
}));
} else {
responseError(request.method + 'Not Acceptable', 406);
responseError(`${request.method} Not Acceptable`, 406);
}
} else if (url.startsWith('/licensereport/')) {
let [, root] = url.split('/licensereport/');
Expand Down
73 changes: 73 additions & 0 deletions API/reuse.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ let LibreTextsFunctions = {
parseURL: parseURL,
cleanPath: cleanPath,
getAPI: getAPI,
getTOC: getTOC,
getUser: getUser,
addProperty: addProperty,
sleep: sleep,
Expand Down Expand Up @@ -924,6 +925,78 @@ async function getAPI(page, getContents, username = undefined) {
return page;
}

/**
* Builds a Table of Contents for a book/text.
*
* The TOC in flat and hierarchical form, or null if error encountered.
*/
async function getTOC(rootURL, username) {
const coverpageData = await getAPI(rootURL, false, username);

async function getRawTOC(page) {
let res = await authenticatedFetch(
page.id,
'tree?dream.out.format=json&include=properties,lastmodified',
page.subdomain,
username,
);
res = await res.json();
return res?.page ?? null;
}

function buildHierarchy(page, parentID) {
const pageID = Number.parseInt(page['@id'], 10);
const subpages = [];

const processPage = (p) => ({
...p,
id: pageID,
subdomain: extractSubdomain(p['uri.ui']),
url: p['uri.ui'],
});

if (Array.isArray(page?.subpages?.page)) {
page.subpages.page.forEach((p) => subpages.push(buildHierarchy(p, pageID)));
} else if (typeof page?.subpages?.page === 'object') {
// single page
subpages.push(buildHierarchy(page.subpages.page, pageID));
}

return processPage({
...page,
...(parentID && { parentID }),
...(subpages.length && { subpages }),
});
}

/**
* Recursively flattens a page hierachy by extracting any subpages and removing
* their container array.
*
* @param {Object} page - Page at the level of the hierarchy to start flattening at.
* @returns {Object[]} The flattened array of page objects.
*/
function flatHierarchy(page) {
let pagesArr = [];
const pageData = { ...page };
if (Array.isArray(pageData.subpages)) {
pageData.subpages.forEach((subpage) => {
pagesArr = [...pagesArr, ...flatHierarchy(subpage)];
});
}
delete pageData.subpages;
pagesArr.unshift(pageData); // add to front to preserve "ordering"
return pagesArr;
}

const rawTOC = await getRawTOC(coverpageData);
if (!rawTOC) return null;
const structured = buildHierarchy(rawTOC);
const flat = flatHierarchy(structured);

return { structured, flat };
}

/**
* Get the information for a particular user
* @param {string} username - user to get information about
Expand Down
6 changes: 3 additions & 3 deletions public/Miscellaneous/reuse.js
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ function LibreTextsReuse() {

async function getRawTOC(page) {
let res = await authenticatedFetch(
page.path,
page.id,
'tree?dream.out.format=json&include=properties,lastmodified',
page.subdomain,
);
Expand All @@ -594,8 +594,8 @@ function LibreTextsReuse() {
}

function buildHierarchy(page, parentID) {
const pageID = Number.parseInt(page['@id']);
let subpages = [];
const pageID = Number.parseInt(page['@id'], 10);
const subpages = [];

const processPage = (p) => ({
...p,
Expand Down

0 comments on commit 4598503

Please sign in to comment.