gdrive-downloader
Version:
Wrapper project to download files from Google Drive
109 lines (108 loc) • 5.81 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GDriveDownloader = void 0;
const axios_1 = __importDefault(require("axios"));
const CSV = __importStar(require("csv-string"));
const fs_1 = __importDefault(require("fs"));
const googleapis_1 = require("googleapis");
// TODO: 2023-01-15 Simon Add logger and log to a file instead (or use events instead )!
// See https://stackoverflow.com/questions/53284918/how-to-log-from-a-npm-package-without-forcing-a-logging-library
class GDriveDownloader {
download(partialConfig) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const config = this.buildConfigWithDefault(partialConfig);
// Build googleapis auth object
const auth = new googleapis_1.google.auth.GoogleAuth({
keyFile: config.pathToCredentialsFile,
scopes: ['https://www.googleapis.com/auth/drive.readonly'],
});
const accesstoken = yield auth.getAccessToken();
// XXX: 2023-01-15 Simon Use good old http request because we can't download a specific sheet from a Google spreadsheet in csv format...
const url = `https://docs.google.com/spreadsheets/d/${config.fileId}/export?exportFormat=csv&gid=${config.sheetId}`;
try {
console.log('Downloading file...');
const res = yield axios_1.default.get(url, { headers: { 'Authorization': `Bearer ${accesstoken}` } });
console.log('File successfully downloaded but not saved to disk yet. Processing...');
let csvData = res.data;
if (!csvData || csvData.length < 1) {
console.log('File is empty. Returning...');
return;
}
const originalDelimiter = CSV.detect(csvData);
console.log('Original delimiter is', originalDelimiter);
// Update csv separator (if necessary)
const targetDelimiter = (_a = config.csvProcessingOptions) === null || _a === void 0 ? void 0 : _a.targetSeparator;
if (targetDelimiter && originalDelimiter !== targetDelimiter) {
console.log('Target delimiter is', targetDelimiter);
// Match delimiter except between quotes (escaping quotes allowed)
// See https://stackoverflow.com/a/11503678
const regex = new RegExp(`${originalDelimiter}(?=(?:(?:\\\\.|[^"\\\\])*"(?:\\\\.|[^"\\\\])*")*(?:\\\\.|[^"\\\\])*$)`, 'g');
csvData = csvData.replace(regex, targetDelimiter);
const newDelimiter = CSV.detect(csvData);
console.log('New delimiter is', CSV.detect(csvData));
if (newDelimiter !== targetDelimiter) {
throw new Error(`Expected delimiter '${targetDelimiter}' not set`);
}
}
// Finally, write file to disk
fs_1.default.writeFileSync(config.destinationFilePath, csvData);
console.log(`File can be found at: ${config.destinationFilePath}`);
}
catch (error) {
console.error(`An error occured: ${error}`);
// Remove created file in case of error
if (fs_1.default.existsSync(config.destinationFilePath)) {
console.log('Deleting tmp file');
fs_1.default.unlinkSync(config.destinationFilePath);
}
}
});
}
buildConfigWithDefault(config) {
return Object.assign({}, GDriveDownloader.DEFAULT_CONFIG, config);
}
}
exports.GDriveDownloader = GDriveDownloader;
GDriveDownloader.DEFAULT_CONFIG = {
fileId: '',
sheetId: '',
pathToCredentialsFile: './credentials.json',
destinationFilePath: './',
csvProcessingOptions: { targetSeparator: ',' }
};