@gyran/google-drive-incomplete-folder-sync
Advanced tools
Comparing version 0.1.0 to 0.2.0
95
index.js
@@ -7,14 +7,53 @@ #!/usr/bin/env node | ||
import fs from 'node:fs'; | ||
import prompts from 'prompts'; | ||
import config from './src/config.js'; | ||
import { delay, ensurePath, fsExists, readDirRecursive } from './src/utils.js'; | ||
import CONFIG from './src/config.js'; | ||
import { | ||
delay, | ||
ensurePath, | ||
fsExists, | ||
readDirRecursive, | ||
writeJSON, | ||
readJSON, | ||
prompt, | ||
} from './src/utils.js'; | ||
// config.clear(); | ||
const writeTokens = async (tokens) => { | ||
await writeJSON(nodePath.join(CONFIG.configPath, 'tokens.json'), tokens); | ||
}; | ||
const readTokens = async () => { | ||
try { | ||
const tokens = await readJSON( | ||
nodePath.join(CONFIG.configPath, 'tokens.json'), | ||
); | ||
return tokens; | ||
} catch (error) { | ||
console.log('could not read tokens', error); | ||
} | ||
return undefined; | ||
}; | ||
const readCurrentState = async () => { | ||
try { | ||
const state = await readJSON( | ||
nodePath.join(CONFIG.configPath, 'state.json'), | ||
); | ||
return state; | ||
} catch (error) { | ||
console.log('could not read state', error); | ||
} | ||
return undefined; | ||
}; | ||
const writeCurrentState = async (state) => { | ||
await writeJSON(nodePath.join(CONFIG.configPath, 'state.json'), state); | ||
}; | ||
const setupAuth = async () => { | ||
const oauth2Client = new google.auth.OAuth2( | ||
config.get('oauthClientId'), | ||
config.get('oauthClientSecret'), | ||
config.get('oauthRedirectUrl'), | ||
CONFIG.oauthClientId, | ||
CONFIG.oauthClientSecret, | ||
CONFIG.oauthRedirectUrl, | ||
); | ||
@@ -24,6 +63,6 @@ | ||
console.log('setting tokens!'); | ||
config.set('tokens', tokens); | ||
writeTokens(tokens); | ||
}); | ||
let tokens = config.get('tokens'); | ||
let tokens = await readTokens(); | ||
if (!tokens) { | ||
@@ -33,10 +72,4 @@ const url = oauth2Client.generateAuthUrl({ | ||
}); | ||
console.log(url); | ||
const promptsResponse = await prompts({ | ||
type: 'text', | ||
name: 'code', | ||
message: 'Code:', | ||
}); | ||
tokens = (await oauth2Client.getToken(promptsResponse.code)).tokens; | ||
const code = await prompt(`${url}\nCode:`); | ||
tokens = (await oauth2Client.getToken(code)).tokens; | ||
} | ||
@@ -85,3 +118,3 @@ | ||
const syncDriveFolder = async (folderFileId, currentPath = '/') => { | ||
const dataPath = config.get('dataPath'); | ||
const dataPath = CONFIG.dataPath; | ||
@@ -113,3 +146,3 @@ await ensurePath(nodePath.join(dataPath, currentPath)); | ||
const saveCurrentSyncState = async () => { | ||
const dataPath = config.get('dataPath'); | ||
const dataPath = CONFIG.dataPath; | ||
const state = { | ||
@@ -130,3 +163,3 @@ files: [], | ||
config.set('currentState', state); | ||
await writeCurrentState(state); | ||
}; | ||
@@ -161,5 +194,5 @@ | ||
const removeDeletedFilesFromDrive = async () => { | ||
const dataPath = config.get('dataPath'); | ||
const rootFolderFileId = config.get('rootFolder'); | ||
const lastState = config.get('currentState'); | ||
const dataPath = CONFIG.dataPath; | ||
const rootFolderFileId = CONFIG.rootFolder; | ||
const lastState = await readCurrentState(); | ||
@@ -185,6 +218,16 @@ if (lastState && Array.isArray(lastState.files)) { | ||
const handleExitSignal = (signal) => { | ||
console.log(`Received ${signal}, exiting`); | ||
process.exit(0); | ||
}; | ||
process.on('SIGINT', handleExitSignal); | ||
process.on('SIGTERM', handleExitSignal); | ||
await ensurePath(CONFIG.configPath); | ||
await ensurePath(CONFIG.dataPath); | ||
await setupAuth(); | ||
const intervalMs = config.get('syncIntervalMs'); | ||
const rootFolderId = config.get('rootFolder'); | ||
const intervalMs = CONFIG.syncIntervalMs; | ||
const rootFolderId = CONFIG.rootFolder; | ||
@@ -198,3 +241,3 @@ console.log('Starting!'); | ||
console.log('Waiting for next loop'); | ||
console.log(`Waiting ${CONFIG.syncIntervalMs} ms for next loop`); | ||
await delay(intervalMs); | ||
@@ -201,0 +244,0 @@ } |
{ | ||
"name": "@gyran/google-drive-incomplete-folder-sync", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "very simple and naive incomplete folder sync with google drive for my personal use", | ||
@@ -19,6 +19,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"conf": "^10.0.3", | ||
"get-env-value": "^4.0.0", | ||
"googleapis": "^87.0.0", | ||
"prompts": "^2.4.1" | ||
"googleapis": "^87.0.0" | ||
}, | ||
@@ -25,0 +23,0 @@ "devDependencies": { |
import getEnvValue from 'get-env-value'; | ||
import Conf from 'conf'; | ||
const schema = { | ||
rootFolder: { | ||
type: 'string', | ||
default: getEnvValue.stringValue('GDIFS_ROOT_FOLDER'), | ||
}, | ||
oauthClientId: { | ||
type: 'string', | ||
default: getEnvValue.stringValue('GDIFS_OAUTH_CLIENT_ID'), | ||
}, | ||
oauthClientSecret: { | ||
type: 'string', | ||
default: getEnvValue.stringValue('GDIFS_OAUTH_CLIENT_SECRET'), | ||
}, | ||
oauthRedirectUrl: { | ||
type: 'string', | ||
default: getEnvValue.stringValue( | ||
'GDIFS_OAUTH_REDIRECT_URL', | ||
'urn:ietf:wg:oauth:2.0:oob', | ||
), | ||
}, | ||
syncIntervalMs: { | ||
type: 'number', | ||
default: getEnvValue.integerValue( | ||
'GDIFS_SYNC_INTERVAL_MS', | ||
600_000, // 10 min | ||
), | ||
}, | ||
dataPath: { | ||
type: 'string', | ||
default: getEnvValue.stringValue('GDIFS_DATA_PATH', '/data'), | ||
}, | ||
currentState: { | ||
type: 'object', | ||
}, | ||
tokens: { | ||
type: 'object', | ||
}, | ||
const CONFIG = { | ||
rootFolder: getEnvValue.stringValue('GDIFS_ROOT_FOLDER'), | ||
oauthClientId: getEnvValue.stringValue('GDIFS_OAUTH_CLIENT_ID'), | ||
oauthClientSecret: getEnvValue.stringValue('GDIFS_OAUTH_CLIENT_SECRET'), | ||
oauthRedirectUrl: getEnvValue.stringValue( | ||
'GDIFS_OAUTH_REDIRECT_URL', | ||
'urn:ietf:wg:oauth:2.0:oob', | ||
), | ||
syncIntervalMs: getEnvValue.integerValue( | ||
'GDIFS_SYNC_INTERVAL_MS', | ||
600_000, // 10 min | ||
), | ||
dataPath: getEnvValue.stringValue('GDIFS_DATA_PATH', '/data'), | ||
configPath: getEnvValue.stringValue('GDIFS_CONFIG_PATH', '/config'), | ||
}; | ||
const config = new Conf({ | ||
schema, | ||
projectName: '@gyran/google-drive-incomplete-folder-sync', | ||
}); | ||
export default config; | ||
export default CONFIG; |
import fsp from 'node:fs/promises'; | ||
import nodePath from 'node:path'; | ||
import readline from 'node:readline'; | ||
@@ -44,1 +45,25 @@ export const delay = (ms) => { | ||
}; | ||
export const readJSON = async (path) => { | ||
const json = JSON.parse(await fsp.readFile(path)); | ||
return json; | ||
}; | ||
export const writeJSON = async (path, data) => { | ||
await fsp.writeFile(path, JSON.stringify(data)); | ||
}; | ||
export const prompt = async (question) => { | ||
return new Promise((resolve) => { | ||
const rl = readline.createInterface({ | ||
input: process.stdin, | ||
output: process.stdout, | ||
}); | ||
rl.question(`${question} `, (answer) => { | ||
resolve(answer); | ||
rl.close(); | ||
}); | ||
}); | ||
}; |
8539
2
263
- Removedconf@^10.0.3
- Removedprompts@^2.4.1
- Removedajv@8.17.1(transitive)
- Removedajv-formats@2.1.1(transitive)
- Removedatomically@1.7.0(transitive)
- Removedconf@10.2.0(transitive)
- Removeddebounce-fn@4.0.0(transitive)
- Removeddot-prop@6.0.1(transitive)
- Removedenv-paths@2.2.1(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-uri@3.0.6(transitive)
- Removedfind-up@3.0.0(transitive)
- Removedis-obj@2.0.0(transitive)
- Removedjson-schema-traverse@1.0.0(transitive)
- Removedjson-schema-typed@7.0.3(transitive)
- Removedkleur@3.0.3(transitive)
- Removedlocate-path@3.0.0(transitive)
- Removedmimic-fn@2.1.03.1.0(transitive)
- Removedonetime@5.1.2(transitive)
- Removedp-limit@2.3.0(transitive)
- Removedp-locate@3.0.0(transitive)
- Removedp-try@2.2.0(transitive)
- Removedpath-exists@3.0.0(transitive)
- Removedpkg-up@3.1.0(transitive)
- Removedprompts@2.4.2(transitive)
- Removedrequire-from-string@2.0.2(transitive)
- Removedsemver@7.7.1(transitive)
- Removedsisteransi@1.0.5(transitive)