Sheets settings (#774)

* wip: migrate sheet settings

---------

Co-authored-by: arc-alex <ac@omnivox.dk>
This commit is contained in:
Carlos Valente
2024-02-17 22:05:38 +01:00
committed by GitHub
parent c1377544a0
commit 5a397c6da7
34 changed files with 732 additions and 701 deletions
+18 -15
View File
@@ -661,12 +661,13 @@ export async function uploadSheetClientFile(req, res: Response) {
}
/**
* @description STEP-1 GET Client Secrect status
* @description STEP-1 GET Client Secret status
*/
export const getClientSecrect = async (req: Request, res: Response) => {
export const getClientSecret = async (req: Request, res: Response) => {
try {
const clientSecrectExists = await sheet.testClientSecret();
if (clientSecrectExists) {
// TODO: can we merge this with the previous?
const clientSecretExists = await sheet.testClientSecret();
if (clientSecretExists) {
res.status(200).send();
} else {
res.status(500).send({ message: 'The Client ID does not exist' });
@@ -706,11 +707,11 @@ export const getAuthentication = async (_req: Request, res: Response) => {
*/
export const postId = async (req: Request, res: Response) => {
try {
const { id } = req.body;
if (id.lenght < 40) {
res.status(400).send({ message: 'ID is usualy 44 characters long' });
const { sheetId } = req.body;
if (sheetId.length < 40) {
res.status(400).send({ message: 'ID is usually 44 characters long' });
}
const state = await sheet.testSheetId(id);
const state = await sheet.testSheetId(sheetId);
res.status(200).send(state);
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -722,8 +723,8 @@ export const postId = async (req: Request, res: Response) => {
*/
export const postWorksheet = async (req: Request, res: Response) => {
try {
const { worksheet, id } = req.body;
const state = await sheet.testWorksheet(worksheet, id);
const { sheetId, worksheet } = req.body;
const state = await sheet.testWorksheet(sheetId, worksheet);
res.status(200).send(state);
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -731,13 +732,15 @@ export const postWorksheet = async (req: Request, res: Response) => {
};
/**
* @description STEP-5 POST download undown to sheet
* @description STEP-5 POST download rundown to sheet
* @returns parsed result
*/
export async function pullSheet(req: Request, res: Response) {
try {
const { id, options } = req.body;
const data = await sheet.pull(id, options);
const { sheetId, options } = req.body;
console.log('starting');
const data = await sheet.pull(sheetId, options);
console.log('finished');
res.status(200).send(data);
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -749,8 +752,8 @@ export async function pullSheet(req: Request, res: Response) {
*/
export async function pushSheet(req: Request, res: Response) {
try {
const { id, options } = req.body;
await sheet.push(id, options);
const { sheetId, options } = req.body;
await sheet.push(sheetId, options);
res.status(200).send();
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -244,8 +244,8 @@ export const validateProjectFiles = (projectFiles: { filename?: string; newFilen
return errors;
};
export const validateSheetid = [
body('id').exists().isString(),
export const validateSheetId = [
body('sheetId').exists().isString(),
(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
@@ -255,7 +255,7 @@ export const validateSheetid = [
];
export const validateWorksheet = [
body('id').exists().isString(),
body('sheetId').exists().isString(),
body('worksheet').exists().isString(),
(req: Request, res: Response, next: NextFunction) => {
@@ -266,7 +266,7 @@ export const validateWorksheet = [
];
export const validateSheetOptions = [
body('id').exists().isString(),
body('sheetId').exists().isString(),
// body('options').exists().isObject(), TODO:
(req: Request, res: Response, next: NextFunction) => {
+7 -5
View File
@@ -31,7 +31,8 @@ import {
pushSheet,
postId,
getAuthentication,
getClientSecrect as getClientSecret,
getClientSecret as getClientSecret,
postWorksheet,
} from '../controllers/ontimeController.js';
import {
@@ -45,7 +46,7 @@ import {
validateProjectDuplicate,
validateLoadProjectFile,
validateProjectRename,
validateSheetid,
validateSheetId,
validateWorksheet,
validateSheetOptions,
} from '../controllers/ontimeController.validate.js';
@@ -126,6 +127,7 @@ router.post('/project', projectSanitiser, createProjectFile);
// create route between controller and '/ontime/project/:filename' endpoint
router.delete('/project/:filename', sanitizeProjectFilename, deleteProjectFile);
// TODO: move the google sheet stuff into a separate file
// Google Sheet integration - Step 1
router.post('/sheet/clientsecret', uploadFile, uploadClientSecret);
router.get('/sheet/clientsecret', uploadFile, getClientSecret);
@@ -135,13 +137,13 @@ router.get('/sheet/authentication/url', getAuthenticationUrl);
router.get('/sheet/authentication', getAuthentication);
// Google Sheet integration - Step 3
router.post('/sheet/id', validateSheetid, postId);
router.post('/sheet/sheetId', validateSheetId, postId);
// Google Sheet integration - Step 4
router.post('/sheet/worksheet', validateWorksheet, postId);
router.post('/sheet/worksheet', validateWorksheet, postWorksheet);
// Google Sheet integration - Step 5
router.post('/sheet/pull', validateSheetOptions, pullSheet);
router.post('/sheet-pull', validateSheetOptions, pullSheet);
// Google Sheet integration - Step 6
router.post('/sheet-push', validateSheetOptions, pushSheet);
+31 -33
View File
@@ -80,7 +80,7 @@ class Sheet {
}
/**
* @description STEP 1 - test that the saved object is pressent
* @description STEP 1 - test that the saved object is present
*/
testClientSecret() {
return Sheet.clientSecret !== null;
@@ -92,18 +92,15 @@ class Sheet {
* @throws
*/
async openAuthServer(): Promise<string | null> {
//TODO: this only works on local networks
//TODO: this only works in local networks
// if the server is allready running retun it
// if the server is already running return it
if (Sheet.authUrl) {
clearTimeout(this.authServerTimeout);
this.authServerTimeout = setTimeout(
() => {
Sheet.authUrl = null;
server.unref();
},
2 * 60 * 1000,
);
this.authServerTimeout = setTimeout(() => {
Sheet.authUrl = null;
server.unref();
}, 120000);
return Sheet.authUrl;
}
@@ -209,12 +206,12 @@ class Sheet {
* @description STEP 3 - test the given sheet id
* @throws
*/
async testSheetId(id: string) {
async testSheetId(sheetId: string) {
const spreadsheets = await sheets({ version: 'v4', auth: Sheet.client }).spreadsheets.get({
spreadsheetId: id,
spreadsheetId: sheetId,
includeGridData: false,
});
if (spreadsheets.status != 200) {
if (spreadsheets.status !== 200) {
throw new Error(spreadsheets.statusText);
}
return { worksheetOptions: spreadsheets.data.sheets.map((i) => i.properties.title) };
@@ -224,12 +221,12 @@ class Sheet {
* @description STEP 4 - test the given worksheet
* @throws
*/
async testWorksheet(id: string, worksheet: string) {
async testWorksheet(sheetId: string, worksheet: string) {
const spreadsheets = await sheets({ version: 'v4', auth: Sheet.client }).spreadsheets.get({
spreadsheetId: id,
spreadsheetId: sheetId,
includeGridData: false,
});
if (spreadsheets.status != 200) {
if (spreadsheets.status !== 200) {
throw new Error(spreadsheets.statusText);
}
const worksheetExist = spreadsheets.data.sheets.find((i) => i.properties.title === worksheet);
@@ -250,17 +247,18 @@ class Sheet {
spreadsheetId: sheetId,
});
if (spreadsheets.status === 200) {
const ourWorksheetData = spreadsheets.data.sheets.find((n) => n.properties.title == worksheet);
if (ourWorksheetData !== undefined) {
const endCell = getA1Notation(
ourWorksheetData.properties.gridProperties.rowCount,
ourWorksheetData.properties.gridProperties.columnCount,
);
return { worksheetId: ourWorksheetData.properties.sheetId, range: `${worksheet}!A1:${endCell}` };
}
} else {
throw new Error('Uable to open spreadsheets');
if (spreadsheets.status !== 200) {
throw new Error(`Request failed: ${spreadsheets.status} ${spreadsheets.statusText}`);
}
const ourWorksheetData = spreadsheets.data.sheets.find((n) => n.properties.title == worksheet);
if (ourWorksheetData !== undefined) {
const endCell = getA1Notation(
ourWorksheetData.properties.gridProperties.rowCount,
ourWorksheetData.properties.gridProperties.columnCount,
);
return { worksheetId: ourWorksheetData.properties.sheetId, range: `${worksheet}!A1:${endCell}` };
}
}
@@ -302,7 +300,7 @@ class Sheet {
updateRundown.push({
deleteDimension: { range: { dimension: 'ROWS', startIndex: titleRow + 2, sheetId: worksheetId } },
});
// insert the lenght of the rundown
// insert the length of the rundown
updateRundown.push({
insertDimension: {
inheritFromBefore: false,
@@ -340,19 +338,19 @@ class Sheet {
}
/**
* @description STEP 5 - Downpload the rundown from sheet
* @param {string} id - id of the sheet https://docs.google.com/spreadsheets/d/[[spreadsheetId]]/edit#gid=0
* @description STEP 5 - Download the rundown from sheet
* @param {string} sheetId - id of the sheet https://docs.google.com/spreadsheets/d/[[spreadsheetId]]/edit#gid=0
* @param {ExcelImportMap} options
* @returns {Promise<Partial<ResponseOK>>}
* @throws
*/
public async pull(id: string, options: ExcelImportMap): Promise<Partial<ResponseOK>> {
const { range } = await this.exist(id, options.worksheet);
public async pull(sheetId: string, options: ExcelImportMap): Promise<Partial<ResponseOK>> {
const { range } = await this.exist(sheetId, options.worksheet);
const res: Partial<ResponseOK> = {};
const googleResponse = await sheets({ version: 'v4', auth: Sheet.client }).spreadsheets.values.get({
spreadsheetId: id,
spreadsheetId: sheetId,
valueRenderOption: 'FORMATTED_VALUE',
majorDimension: 'ROWS',
range,