dropbox should use sub folder
This commit is contained in:
parent
e9e9e2b6eb
commit
2e800af4f8
@ -110,6 +110,7 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
this.settings.s3,
|
this.settings.s3,
|
||||||
this.settings.webdav,
|
this.settings.webdav,
|
||||||
this.settings.dropbox,
|
this.settings.dropbox,
|
||||||
|
this.app.vault.getName(),
|
||||||
() => self.saveSettings()
|
() => self.saveSettings()
|
||||||
);
|
);
|
||||||
const remoteRsp = await client.listFromRemote();
|
const remoteRsp = await client.listFromRemote();
|
||||||
@ -349,6 +350,7 @@ export class DropboxAuthModal extends Modal {
|
|||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
this.plugin.settings.dropbox,
|
this.plugin.settings.dropbox,
|
||||||
|
this.app.vault.getName(),
|
||||||
() => self.plugin.saveSettings()
|
() => self.plugin.saveSettings()
|
||||||
);
|
);
|
||||||
const username = await client.getUser();
|
const username = await client.getUser();
|
||||||
@ -626,6 +628,7 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
|||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
this.plugin.settings.dropbox,
|
this.plugin.settings.dropbox,
|
||||||
|
this.app.vault.getName(),
|
||||||
() => self.plugin.saveSettings()
|
() => self.plugin.saveSettings()
|
||||||
);
|
);
|
||||||
await client.revokeAuth();
|
await client.revokeAuth();
|
||||||
@ -687,6 +690,7 @@ class RemotelySaveSettingTab extends PluginSettingTab {
|
|||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
this.plugin.settings.dropbox,
|
this.plugin.settings.dropbox,
|
||||||
|
this.app.vault.getName(),
|
||||||
() => self.plugin.saveSettings()
|
() => self.plugin.saveSettings()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ export class RemoteClient {
|
|||||||
s3Config?: s3.S3Config,
|
s3Config?: s3.S3Config,
|
||||||
webdavConfig?: webdav.WebdavConfig,
|
webdavConfig?: webdav.WebdavConfig,
|
||||||
dropboxConfig?: dropbox.DropboxConfig,
|
dropboxConfig?: dropbox.DropboxConfig,
|
||||||
|
vaultName?: string,
|
||||||
saveUpdatedConfigFunc?: () => Promise<any>
|
saveUpdatedConfigFunc?: () => Promise<any>
|
||||||
) {
|
) {
|
||||||
this.serviceType = serviceType;
|
this.serviceType = serviceType;
|
||||||
@ -31,12 +32,15 @@ export class RemoteClient {
|
|||||||
this.webdavConfig = webdavConfig;
|
this.webdavConfig = webdavConfig;
|
||||||
this.webdavClient = webdav.getWebdavClient(this.webdavConfig);
|
this.webdavClient = webdav.getWebdavClient(this.webdavConfig);
|
||||||
} else if (serviceType === "dropbox") {
|
} else if (serviceType === "dropbox") {
|
||||||
if (saveUpdatedConfigFunc === undefined) {
|
if (vaultName === undefined || saveUpdatedConfigFunc === undefined) {
|
||||||
throw Error("remember to provide callback while init dropbox client");
|
throw Error(
|
||||||
|
"remember to provide vault name and callback while init dropbox client"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.dropboxConfig = dropboxConfig;
|
this.dropboxConfig = dropboxConfig;
|
||||||
this.dropboxClient = dropbox.getDropboxClient(
|
this.dropboxClient = dropbox.getDropboxClient(
|
||||||
this.dropboxConfig,
|
this.dropboxConfig,
|
||||||
|
vaultName,
|
||||||
saveUpdatedConfigFunc
|
saveUpdatedConfigFunc
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -37,10 +37,11 @@ export const DEFAULT_DROPBOX_CONFIG = {
|
|||||||
username: "",
|
username: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDropboxPath = (fileOrFolderPath: string) => {
|
export const getDropboxPath = (fileOrFolderPath: string, vaultName: string) => {
|
||||||
let key = fileOrFolderPath;
|
let key = fileOrFolderPath;
|
||||||
if (!fileOrFolderPath.startsWith("/")) {
|
if (!fileOrFolderPath.startsWith("/")) {
|
||||||
key = `/${fileOrFolderPath}`;
|
// then this is original path in Obsidian
|
||||||
|
key = `/${vaultName}/${fileOrFolderPath}`;
|
||||||
}
|
}
|
||||||
if (key.endsWith("/")) {
|
if (key.endsWith("/")) {
|
||||||
key = key.slice(0, key.length - 1);
|
key = key.slice(0, key.length - 1);
|
||||||
@ -48,20 +49,26 @@ export const getDropboxPath = (fileOrFolderPath: string) => {
|
|||||||
return key;
|
return key;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNormPath = (fileOrFolderPath: string) => {
|
const getNormPath = (fileOrFolderPath: string, vaultName: string) => {
|
||||||
if (fileOrFolderPath.startsWith("/")) {
|
if (
|
||||||
return fileOrFolderPath.slice(1);
|
!(
|
||||||
|
fileOrFolderPath === `/${vaultName}` ||
|
||||||
|
fileOrFolderPath.startsWith(`/${vaultName}/`)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw Error(`"${fileOrFolderPath}" doesn't starts with "/${vaultName}/"`);
|
||||||
}
|
}
|
||||||
return fileOrFolderPath;
|
return fileOrFolderPath.slice(`/${vaultName}/`.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fromDropboxItemToRemoteItem = (
|
const fromDropboxItemToRemoteItem = (
|
||||||
x:
|
x:
|
||||||
| files.FileMetadataReference
|
| files.FileMetadataReference
|
||||||
| files.FolderMetadataReference
|
| files.FolderMetadataReference
|
||||||
| files.DeletedMetadataReference
|
| files.DeletedMetadataReference,
|
||||||
|
vaultName: string
|
||||||
): RemoteItem => {
|
): RemoteItem => {
|
||||||
let key = getNormPath(x.path_display);
|
let key = getNormPath(x.path_display, vaultName);
|
||||||
if (x[".tag"] === "folder" && !key.endsWith("/")) {
|
if (x[".tag"] === "folder" && !key.endsWith("/")) {
|
||||||
key = `${key}/`;
|
key = `${key}/`;
|
||||||
}
|
}
|
||||||
@ -261,17 +268,23 @@ export const setConfigBySuccessfullAuthInplace = async (
|
|||||||
|
|
||||||
export class WrappedDropboxClient {
|
export class WrappedDropboxClient {
|
||||||
dropboxConfig: DropboxConfig;
|
dropboxConfig: DropboxConfig;
|
||||||
|
vaultName: string;
|
||||||
saveUpdatedConfigFunc: () => Promise<any>;
|
saveUpdatedConfigFunc: () => Promise<any>;
|
||||||
dropbox: Dropbox;
|
dropbox: Dropbox;
|
||||||
|
vaultFolderExists: boolean;
|
||||||
constructor(
|
constructor(
|
||||||
dropboxConfig: DropboxConfig,
|
dropboxConfig: DropboxConfig,
|
||||||
|
vaultName: string,
|
||||||
saveUpdatedConfigFunc: () => Promise<any>
|
saveUpdatedConfigFunc: () => Promise<any>
|
||||||
) {
|
) {
|
||||||
this.dropboxConfig = dropboxConfig;
|
this.dropboxConfig = dropboxConfig;
|
||||||
|
this.vaultName = vaultName;
|
||||||
this.saveUpdatedConfigFunc = saveUpdatedConfigFunc;
|
this.saveUpdatedConfigFunc = saveUpdatedConfigFunc;
|
||||||
|
this.vaultFolderExists = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
init = async () => {
|
init = async () => {
|
||||||
|
// check token
|
||||||
if (
|
if (
|
||||||
this.dropboxConfig.accessToken === "" ||
|
this.dropboxConfig.accessToken === "" ||
|
||||||
this.dropboxConfig.refreshToken === ""
|
this.dropboxConfig.refreshToken === ""
|
||||||
@ -303,6 +316,33 @@ export class WrappedDropboxClient {
|
|||||||
accessToken: this.dropboxConfig.accessToken,
|
accessToken: this.dropboxConfig.accessToken,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check vault folder
|
||||||
|
// console.log(`checking remote has folder /${this.vaultName}`);
|
||||||
|
if (this.vaultFolderExists) {
|
||||||
|
// console.log(`already checked, /${this.vaultName} exist before`)
|
||||||
|
} else {
|
||||||
|
const res = await this.dropbox.filesListFolder({
|
||||||
|
path: "",
|
||||||
|
recursive: false,
|
||||||
|
});
|
||||||
|
for (const item of res.result.entries) {
|
||||||
|
if (item.path_display === `/${this.vaultName}`) {
|
||||||
|
this.vaultFolderExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.vaultFolderExists) {
|
||||||
|
console.log(`remote does not have folder /${this.vaultName}`);
|
||||||
|
await this.dropbox.filesCreateFolderV2({
|
||||||
|
path: `/${this.vaultName}`,
|
||||||
|
});
|
||||||
|
console.log(`remote folder /${this.vaultName} created`);
|
||||||
|
} else {
|
||||||
|
// console.log(`remote folder /${this.vaultName} exists`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this.dropbox;
|
return this.dropbox;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -313,9 +353,14 @@ export class WrappedDropboxClient {
|
|||||||
*/
|
*/
|
||||||
export const getDropboxClient = (
|
export const getDropboxClient = (
|
||||||
dropboxConfig: DropboxConfig,
|
dropboxConfig: DropboxConfig,
|
||||||
|
vaultName: string,
|
||||||
saveUpdatedConfigFunc: () => Promise<any>
|
saveUpdatedConfigFunc: () => Promise<any>
|
||||||
) => {
|
) => {
|
||||||
return new WrappedDropboxClient(dropboxConfig, saveUpdatedConfigFunc);
|
return new WrappedDropboxClient(
|
||||||
|
dropboxConfig,
|
||||||
|
vaultName,
|
||||||
|
saveUpdatedConfigFunc
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRemoteMeta = async (
|
export const getRemoteMeta = async (
|
||||||
@ -328,7 +373,7 @@ export const getRemoteMeta = async (
|
|||||||
// we instead try to list files
|
// we instead try to list files
|
||||||
// if no error occurs, we ensemble a fake result.
|
// if no error occurs, we ensemble a fake result.
|
||||||
const rsp = await client.dropbox.filesListFolder({
|
const rsp = await client.dropbox.filesListFolder({
|
||||||
path: "",
|
path: `/${client.vaultName}`,
|
||||||
recursive: false, // don't need to recursive here
|
recursive: false, // don't need to recursive here
|
||||||
});
|
});
|
||||||
if (rsp.status !== 200) {
|
if (rsp.status !== 200) {
|
||||||
@ -343,7 +388,7 @@ export const getRemoteMeta = async (
|
|||||||
} as RemoteItem;
|
} as RemoteItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = getDropboxPath(fileOrFolderPath);
|
const key = getDropboxPath(fileOrFolderPath, client.vaultName);
|
||||||
|
|
||||||
const rsp = await client.dropbox.filesGetMetadata({
|
const rsp = await client.dropbox.filesGetMetadata({
|
||||||
path: key,
|
path: key,
|
||||||
@ -351,7 +396,7 @@ export const getRemoteMeta = async (
|
|||||||
if (rsp.status !== 200) {
|
if (rsp.status !== 200) {
|
||||||
throw Error(JSON.stringify(rsp));
|
throw Error(JSON.stringify(rsp));
|
||||||
}
|
}
|
||||||
return fromDropboxItemToRemoteItem(rsp.result);
|
return fromDropboxItemToRemoteItem(rsp.result, client.vaultName);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const uploadToRemote = async (
|
export const uploadToRemote = async (
|
||||||
@ -369,7 +414,7 @@ export const uploadToRemote = async (
|
|||||||
if (password !== "") {
|
if (password !== "") {
|
||||||
uploadFile = remoteEncryptedKey;
|
uploadFile = remoteEncryptedKey;
|
||||||
}
|
}
|
||||||
uploadFile = getDropboxPath(uploadFile);
|
uploadFile = getDropboxPath(uploadFile, client.vaultName);
|
||||||
|
|
||||||
const isFolder = fileOrFolderPath.endsWith("/");
|
const isFolder = fileOrFolderPath.endsWith("/");
|
||||||
|
|
||||||
@ -425,7 +470,9 @@ export const uploadToRemote = async (
|
|||||||
});
|
});
|
||||||
// we want to mark that parent folders are created
|
// we want to mark that parent folders are created
|
||||||
if (foldersCreatedBefore !== undefined) {
|
if (foldersCreatedBefore !== undefined) {
|
||||||
const dirs = getFolderLevels(uploadFile).map(getDropboxPath);
|
const dirs = getFolderLevels(uploadFile).map((x) =>
|
||||||
|
getDropboxPath(x, client.vaultName)
|
||||||
|
);
|
||||||
for (const dir of dirs) {
|
for (const dir of dirs) {
|
||||||
foldersCreatedBefore?.add(dir);
|
foldersCreatedBefore?.add(dir);
|
||||||
}
|
}
|
||||||
@ -443,7 +490,7 @@ export const listFromRemote = async (
|
|||||||
}
|
}
|
||||||
await client.init();
|
await client.init();
|
||||||
const res = await client.dropbox.filesListFolder({
|
const res = await client.dropbox.filesListFolder({
|
||||||
path: "",
|
path: `/${client.vaultName}`,
|
||||||
recursive: true,
|
recursive: true,
|
||||||
});
|
});
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
@ -453,7 +500,8 @@ export const listFromRemote = async (
|
|||||||
const contents = res.result.entries;
|
const contents = res.result.entries;
|
||||||
const unifiedContents = contents
|
const unifiedContents = contents
|
||||||
.filter((x) => x[".tag"] !== "deleted")
|
.filter((x) => x[".tag"] !== "deleted")
|
||||||
.map(fromDropboxItemToRemoteItem);
|
.filter((x) => x.path_display !== `/${client.vaultName}`)
|
||||||
|
.map((x) => fromDropboxItemToRemoteItem(x, client.vaultName));
|
||||||
fixLastModifiedTimeInplace(unifiedContents);
|
fixLastModifiedTimeInplace(unifiedContents);
|
||||||
return {
|
return {
|
||||||
Contents: unifiedContents,
|
Contents: unifiedContents,
|
||||||
@ -465,7 +513,7 @@ const downloadFromRemoteRaw = async (
|
|||||||
fileOrFolderPath: string
|
fileOrFolderPath: string
|
||||||
) => {
|
) => {
|
||||||
await client.init();
|
await client.init();
|
||||||
const key = getDropboxPath(fileOrFolderPath);
|
const key = getDropboxPath(fileOrFolderPath, client.vaultName);
|
||||||
const rsp = await client.dropbox.filesDownload({
|
const rsp = await client.dropbox.filesDownload({
|
||||||
path: key,
|
path: key,
|
||||||
});
|
});
|
||||||
@ -505,7 +553,7 @@ export const downloadFromRemote = async (
|
|||||||
if (password !== "") {
|
if (password !== "") {
|
||||||
downloadFile = remoteEncryptedKey;
|
downloadFile = remoteEncryptedKey;
|
||||||
}
|
}
|
||||||
downloadFile = getDropboxPath(downloadFile);
|
downloadFile = getDropboxPath(downloadFile, client.vaultName);
|
||||||
const remoteContent = await downloadFromRemoteRaw(client, downloadFile);
|
const remoteContent = await downloadFromRemoteRaw(client, downloadFile);
|
||||||
let localContent = remoteContent;
|
let localContent = remoteContent;
|
||||||
if (password !== "") {
|
if (password !== "") {
|
||||||
@ -530,7 +578,7 @@ export const deleteFromRemote = async (
|
|||||||
if (password !== "") {
|
if (password !== "") {
|
||||||
remoteFileName = remoteEncryptedKey;
|
remoteFileName = remoteEncryptedKey;
|
||||||
}
|
}
|
||||||
remoteFileName = getDropboxPath(remoteFileName);
|
remoteFileName = getDropboxPath(remoteFileName, client.vaultName);
|
||||||
|
|
||||||
await client.init();
|
await client.init();
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user