File not found google drive API - node.js

I am trying to list files and trash some file from it but the update API throwing error file not find. Though list API is returning me the result and I am passing the same file id to the update API.
drive.files.list(
{
q:
"mimeType='application/zip' and name = '" +
prevFileName +
"' and '" +
parent +
"' in parents",
fields: "files(kind,id,name,mimeType,teamDriveId,parents,createdTime)",
corpora: "drive",
includeTeamDriveItems: true,
supportsTeamDrives: true,
teamDriveId: teamDriveId
},
(err, res) => {
if (err) {
console.log("Error listing files ", err.message);
} else {
const prevFiles = res && res.data && res.data.files;
console.log("prevFiles : ", prevFiles);
if (prevFiles && prevFiles[0] && prevFiles[0].name === prevFileName) {
drive.files.update(
{
fileId: prevFiles[0].id
},
{ resource: { trashed: true } },
(err, result) => {
if (!err) {
console.log("Prev file successfully deleted : ", result);
resolve("File upload SuccessFully: ", file.data);
} else {
console.error("Error removing prev file :: ", err);
}
}
);
}
}
}
);
Here I am getting a file with some json response
[ { kind: 'drive#file',
id: 'ksnadoasjndajn12n1n212',
name: 'xxx_x_x.zip',
mimeType: 'application/zip',
parents: [ 'xxxx-sandadaadakmke' ],
createdTime: '2021-07-14T06:12:11.169Z',
teamDriveId: 'xxxonaijsojxxx' } ]
But when I am passing this id in update API it is throwing error.
My Auth scopes are
var SCOPES = [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.appdata",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive.metadata.readonly",
"https://www.googleapis.com/auth/drive.metadata",
"https://www.googleapis.com/auth/drive.photos.readonly"
];
Please help me out in this.
Thanks.

Since your drive.files.list request contains includeTeamDriveItems: true and supportsTeamDrives: true, you should specify the respective option for drive.files.update
By default supportsAllDrives is set to false unless you explicitly set it to true.
Thuss, files located on a team drive will not be found.
Note: supportsTeamDrives is deprecated, setting supportsAllDrives to true is enough.

Related

Sppull library: download files returning empty array for sharepoint files

Code:
const context = {
siteUrl: 'https://<tenant>.sharepoint.com',
creds: {
username: "<username>#<tenant>.onmicrosoft.com",
password: "***",
online: true
}
};
const options2 = {
spRootFolder: "Shared%20Documents/docverify",
dlRootFolder: "./docverify"
};
SPPull.download(context, options2)
.then((downloadResults) => {
console.log("Files are downloaded", downloadResults);
console.log("For more, please check the results", JSON.stringify(downloadResults));
})
.catch((err) => {
console.log("Core error has happened", err);
});
Output:
Files are downloaded []
For more please check the results []
Attached screenshot of the file in sharepoint
enter image description here
Files to be downloaded

Adding additional spec files to an angular project, not loading/defining correctly?

Caveat: I am not the author of this project. Whoever originally wrote this is no longer with the organization and I am seemingly the most knowledgeable on this topic at this point.
I know a little about javascript and unit tests, so I successfully added one .spec.js file. I tried adding a second one for another module, reusing a lot of the spec setup, and it immediately broke.
Project resources:
Nodejs 12.16.1
jasmine-node-karma: "^1.6.1"
karma: "^6.3.12"
Contents of ./karma.conf.js:
module.exports = function(config) {
config.set({
basePath: './public',
frameworks: ['jasmine', 'jquery-3.2.1'],
files: [
"../node_modules/angular/angular.js",
"../node_modules/angular-mocks/angular-mocks.js",
"../node_modules/bootstrap/dist/js/bootstrap.js",
"../public/**/*.js",
],
exclude: [
],
preprocessors: {
},
client: {
captureConsole: true
},
browserConsoleLogOptions: {
terminal: true,
level: ""
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['FirefoxHeadless', 'ChromeHeadlessNoSandbox', 'PhantomJS'],
customLaunchers: {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
flags: ['--no-sandbox']
},
FirefoxHeadless: {
base: 'Firefox',
flags: ['-headless'],
}
},
singleRun: false,
concurrency: Infinity
})
}
Originally I added ./public/controllers.spec.js to match the existing ./public/controllers.js. These unit tests pass and continue to do so.
Yesterday I added ./public/backups/backupcontrollers.spec.js to match ./public/backups/backupcontrollers.js.
Contents of ./public/backups/backupcontrollers.js:
/**
* Angular controller.
*/
'use strict'
const backupApp = angular.module('backup', [])
const backupTypePath = 'elasticsearch'
backupApp.controller('BackupFormController', ['$scope', '$filter', '$http', function ($scope, $filter, $http) {
console.log('Started BackupFormController')
$scope.itemInstances = []
$scope.fetchStatus = 'Ready!'
$scope.processSelection = function (item, backupType = backupTypePath) {
$scope.currentItem = item.metadata.name
$scope.getBackup(backupType)
console.log('currentItem after selecting from dropdown: ' + $scope.currentItem)
}
$scope.init = function (backupType = backupTypePath) {
$scope.refreshItemInstances(backupType)
console.log('currentItem after loading page for first time: ' + $scope.currentItem)
}
$scope.getBackup = function (backupType = backupTypePath) {
const path = `/v1/backup/${backupType}`
$scope.fetchStatus = `Fetching Backups for Item ${$scope.currentItem}...`
console.log(`Fetching backups for item from ${path}`)
$http.get('/api', { headers: { path: path, item: $scope.currentItem } })
.success(function (data, status, headers, config) {
console.log(`Got data from GET on path ${path}, HTTP status ${status}: ${JSON.stringify(data)}`)
if (typeof data === 'string' || data instanceof String) {
$scope.backups = data.split(/\r?\n/)
} else {
$scope.backups = data
}
$scope.fetchStatus = 'Ready!'
console.log('Done fetching backup list for item:' + $scope.currentItem + '!')
})
.error(function (data, status, header, config) {
console.log(data)
$scope.fetchStatus = 'Ready!'
})
}
// Refresh the list of displayed Item instances
$scope.refreshItemInstances = function (backupType = backupTypePath) {
console.log('Fetching list of all items in the system ...')
$scope.fetchStatus = 'Fetching Items ... '
$http.get('/env')
.success(function (data, status, headers, config) {
console.log(data)
for (let i = 0; i < data.length; i++) {
$scope.itemInstances.push(data[i])
}
$scope.currentItem = $scope.itemInstances[0].metadata.name
console.log('Done fetching list of all items!')
console.log('currentItem after fetching list of all items: ' + $scope.currentItem)
$scope.fetchStatus = 'Ready!'
$scope.getBackup(backupType)
})
.error(function (data, status, header, config) {
console.log(data)
$scope.fetchStatus = 'Ready!'
})
}
}])
Contents of ./public/backups/backupcontrollers.spec.js:
describe('BackupFormController', function () {
let $controller, $rootScope, $httpBackend
beforeEach(module('backup'))
const mockBackupString = 'string of backup data'
const mockBackupData = {
body: mockBackupString
}
const mockItemsUnsorted = [
{
metadata: {
name: 'prod-mock-1',
spec: 'asdf',
status: 'ok'
},
notes: []
},
{
metadata: {
name: 'dev-mock-1',
spec: 'asdf',
status: 'ok'
},
notes: []
},
{
metadata: {
name: 'integ-mock-1',
spec: 'asdf',
status: 'ok'
},
notes: []
}
]
beforeEach(inject(function ($injector) {
$rootScope = $injector.get('$rootScope')
const $controller = $injector.get('$controller')
$httpBackend = $injector.get('$httpBackend')
const mockEnv = $httpBackend.when('GET', '/env')
.respond(mockItemsUnsorted)
const mockAPI = $httpBackend.when('GET', '/api')
.respond(mockBackupString)
const createController = function () {
return $controller('BackupFormController', { '$scope': $rootScope })
}
}))
describe('$scope.getBackup', function () {
beforeEach(function () {
spyOn(console, 'log')
})
it('should GET /api and set $scope.backups', function () {
controller = createController()
console.log('Dumping fetchStatus: ', $rootScope.fetchStatus)
$rootScope.init()
$httpBackend.flush()
expect($rootScope.backups).toEqual(mockBackupString)
expect(console.log).toHaveBeenCalled()
})
})
})
It seems like this new spec isn't working correctly at all; when I run npm test I see the normal successful tests from ./public/controllers.spec.js but also:
Chrome Headless 105.0.5195.125 (Mac OS 10.15.7) BackupFormController $scope.getBackup should GET /api and set $scope.backups FAILED
ReferenceError: createController is not defined
at UserContext.<anonymous> (backup/backupcontrollers.spec.js:51:7)
at <Jasmine>
This is the only output concerning ./public/backups/backupcontrollers.spec.js.
Has anybody run into this before? I found some posts regarding including angular-mocks, but as you can see in karma.conf.js, it's being included.

NodeJS get Google Sheet list

I have a google sheet with a list (dropdown, or data validation - list from ranges, as Google Sheets call it), like so:
Image of sheet
Imagine that in the list I have 4 values to select from. My goal is not only to get all table values, but also all values that constitute the list ["Beer","Wine","Rum","Martini"].
I've tried 2 different ways to retrieve the info and the list:
a) With sheets.spreadsheets.values.get, I get the table values in a digestible way, but not the content of the dropdown. Instead, the cell comes in as blank ("") [Comment: on Apps Script, you would get this information]
b) With sheets.spreadsheets.getByDataFilter, I get much more than I need and in a horrible format. However, I do not get the dropdown content as an array (as I'd want), but rather as a refence: (userEnteredValue: "=Input!$F$5:$F$7")
The question is, how do I get only the table, including the dropdown content as an array? I know it is possible and easy to do in Google Apps Script (I have it implemented), but not on Node.
Below the code as a reference for other programmers.
var {google} = require("googleapis");
let privatekey = require("./client_secret.json");
// configure a JWT auth client
let jwtClient = new google.auth.JWT(
privatekey.client_email,
null,
privatekey.private_key,
['https://www.googleapis.com/auth/spreadsheets',
]);
//authenticate request
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
} else {
console.log("Successfully connected!");
}
});
//Google Sheets API
let spreadsheetId = '<SPREADSHEET ID>';
let sheetName = 'Input!A1:B4'
let sheets = google.sheets('v4');
exports.fetch = (req, res) => {
sheets.spreadsheets.values.get({
auth: jwtClient,
spreadsheetId: spreadsheetId,
range: sheetName,
}, function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
} else {
res.json(response);
}
});
// OR
sheets.spreadsheets.getByDataFilter({
auth: jwtClient,
spreadsheetId: spreadsheetId,
"includeGridData": true,
}, function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
} else {
res.json(response);
}
});
}
What you are interested in is dataValidation
In order to retrieve it, you can use the method spreadsheets.get, setting the parameter fields to sheets/data/rowData/values/dataValidation
If your data validation is set as List of items, the response will look like:
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"dataValidation": {
"condition": {
"type": "ONE_OF_LIST",
"values": [
{
"userEnteredValue": "Beer"
},
{
"userEnteredValue": "Wine"
},
{
"userEnteredValue": "Martini"
}
]
},
"showCustomUi": true
}
}
]
}
]
}
]
}
]
}
If your data validation is set as List form a range the response will look like:
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
{
"dataValidation": {
"condition": {
"type": "ONE_OF_RANGE",
"values": [
{
"userEnteredValue": "=Sheet1!$B$1:$B$3"
}
]
},
"showCustomUi": true
}
}
]
}
]
}
]
}
]
}
In the latter case you would need to call subsequently the method spreadsheets.values.get on =Sheet1!$B$1:$B$3 - that is the range returned as userEnteredValue within the object values nested within the object dataValidation.

How to create electron auto updates using private github repository?

The update is being detected but I'm unable to download it to my app.
I get the following error:
Status: Update Available
Status: Error in auto-updater. Error: Cannot download "https://api.github.com/repos/[username]/[repo-name]/releases/assets/15151663", status 404: Not Found.
The problem appears only using private github repository not public!!
I've tried installing auto updates to a clean electron react-boilerplate and it works perfectly fine with private github repository.. So i'm a bit at a loss what to do here..
I did some research and it seems like app-update.yml should contain github token (electron-builder should generate it) but my app-update.yml (which is located in release/win-unpacked/resources) does not contain a token...
It only contains this info:
owner: [username]
repo: [repo-name]
provider: github
updaterCacheDirName: [appname]
How can I generate it?
Other comment states that I should have a separate release-only repository which I do, but it still doesn't work.
Electron Autoupdater with Private GitHub Repository?
Other people say that downgrading versions fix this problem, but I also saw people say that doesn't fix it and downgrading isn't really a good option.
My steps of adding gh-token:
I setup my github info in package.json (this token is being ignored)
"publish": {
"provider": "github",
"owner": "[username]",
"repo": "[repo-name]",
"token": "[gh-token]",
"private": true
}
"repository": {
"type": "git",
"url": "https://github.com/[username]/[repo-name].git"
},
So I add it to my main.js aswell just in case.
autoUpdater.setFeedURL({
provider: 'github',
repo: '[repo-name]',
owner: '[username]',
private: true,
token: '[gh-token]'
});
process.env.GH_TOKEN = "[gh-token]";
When I remove setFeedURL I get the exact same error as in this questions:
https://github.com/electron-userland/electron-builder/issues/2641
latest.yml (generated file in github releases along side installer.exe installer.exe.blockmap and installer.msi)
version: [version-number]
files:
- url: [app-name.exe]
sha512: [string]
size: [file-size]
path: [app-name.exe]
sha512: [string]
releaseDate: [release-date]
versions i'm using:
"electron": "^3.0.10",
"electron-builder": "^20.38.4",
"electron-updater": "^4.0.0",
full main.js
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import MenuBuilder from './menu';
export default class AppUpdater {
constructor() {
log.transports.file.level = 'info';
autoUpdater.logger = log;
autoUpdater.checkForUpdatesAndNotify();
}
}
let mainWindow = null;
autoUpdater.setFeedURL({
provider: 'github',
repo: '[repo-name]',
owner: '[username]',
private: true,
token: '[gh-token]'
});
process.env.GH_TOKEN = "[gh-token]";
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support');
sourceMapSupport.install();
}
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
require('electron-debug')();
}
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
return Promise.all(
extensions.map(name => installer.default(installer[name], forceDownload))
).catch(console.log);
};
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
const sendStatusToWindow = (text) => {
log.info(text);
if(mainWindow){
mainWindow.webContents.send('message', text);
}
}
autoUpdater.on('checking-for-update', () => {
sendStatusToWindow('Checking for update...');
});
autoUpdater.on('update-available', (info) => {
sendStatusToWindow('Update available.');
dialog.showMessageBox({
message: 'update available !!'
});
});
autoUpdater.on('update-not-available', (info) => {
sendStatusToWindow('Update not available.');
});
autoUpdater.on('error', (err) => {
sendStatusToWindow('Error in auto-updater. ' + err);
});
autoUpdater.on('download-progress', (progressObj) => {
let log_message = "Download speed: " + progressObj.bytesPerSecond;
log_message = log_message + ' - Downloaded ' + progressObj.percent + '%';
log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
sendStatusToWindow(log_message);
})
autoUpdater.on('update-downloaded', (info) => {
sendStatusToWindow('Update downloaded');
dialog.showMessageBox({
message: 'Update downloaded, restarting app..'
});
autoUpdater.quitAndInstall();
});
app.on('ready', async () => {
autoUpdater.checkForUpdatesAndNotify();
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
await installExtensions();
}
mainWindow = new BrowserWindow({
show: false,
width: 1024,
height: 728
});
mainWindow.webContents.openDevTools();
mainWindow.loadURL(`file://${__dirname}/app.html`);
mainWindow.webContents.on('did-finish-load', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env.START_MINIMIZED) {
mainWindow.minimize();
} else {
mainWindow.show();
mainWindow.focus();
}
});
mainWindow.on('closed', () => {
mainWindow = null;
});
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder.buildMenu();
new AppUpdater();
});
I package my app using:
"package": "yarn build && electron-builder build --publish never"
And then I publish it to github releases using:
"gh-publish": "electron-builder --x64 -p always"
import {autoUpdater} from 'electron-updater';
autoUpdater.setFeedURL({
provider: 'github',
owner: 'your_username',
repo: 'your_repo_name',
private: true,
token: process.env.GH_TOKEN, // provide your github access token, with repo:access
});
For the reference to pulling the update, look into this repo:
https://github.com/iffy/electron-updater-example

File creation is ignoring my parameters but creates an "Untitled" binary file

Using the Google API via the googleapis package and the file.create call simply does not work. I've experimented making the same call in Google's API Explorer and it does work. I'm at a bit of a loss.
The createSheet call is encapsulated as follows :
Google.prototype.createSheet = function(filename, callback) {
var services = google.drive('v3');
services.files.create({
"name" : filename,
"mimeType" : "application/vnd.google-apps.spreadsheet",
"description" : 'auto-generated by the cli',
"auth" : this.auth
}, function(err,response) {
if( err ) {
console.log('Error : unable to create file, ' + err);
return;
} else {
console.dir(response);
}
});
}
... the net result is,
{ kind: 'drive#file',
id: '0BwWAQdfAgbYzWk5XRFQyODQ0Zmc',
name: 'Untitled',
mimeType: 'application/octet-stream'
}
It's missing both the filename as well as the filetype.
The general framework here is working correctly as I can get a list of files and read from spreadsheets.

Resources