Skip to content

Commit

Permalink
Feature: Backup now supports uploading files and folders
Browse files Browse the repository at this point in the history
  • Loading branch information
ArceDanielShok committed Aug 9, 2024
1 parent 20bd288 commit f5568c8
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 44 deletions.
4 changes: 1 addition & 3 deletions .erb/configs/webpack.config.backups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import webpackPaths from './webpack.paths';
import Dotenv from 'dotenv-webpack';

const configuration: webpack.Configuration = {
mode:
(process.env.NODE_ENV as 'development' | 'production' | 'none') ||
'development',
mode: process.env.NODE_ENV,

target: 'electron-renderer',

Expand Down
74 changes: 46 additions & 28 deletions src/apps/backups/Backups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
FoldersDiff,
FoldersDiffCalculator,
} from './diff/FoldersDiffCalculator';
import { relative } from './utils/relative';
import { getParentDirectory, relative, relativeV2 } from './utils/relative';

Check warning on line 20 in src/apps/backups/Backups.ts

View workflow job for this annotation

GitHub Actions / 🧪 Lint and test

'relative' is defined but never used
import { DriveDesktopError } from '../../context/shared/domain/errors/DriveDesktopError';
import { UserAvaliableSpaceValidator } from '../../context/user/usage/application/UserAvaliableSpaceValidator';
import { FileDeleter } from '../../context/virtual-drive/files/application/delete/FileDeleter';
Expand Down Expand Up @@ -49,19 +49,32 @@ export class Backup {
info.pathname as AbsolutePath
);

Logger.debug('[BACKUPS] Local tree either', localTreeEither);

if (localTreeEither.isLeft()) {
Logger.error('[BACKUPS] local tree is left', localTreeEither);
return localTreeEither.getLeft();
}

const local = localTreeEither.getRight();

Logger.info('[BACKUPS] Generating remote tree');
Logger.info('[BACKUPS] Generating remote tree', info.folderId);
const remote = await this.remoteTreeBuilder.run(info.folderId);

Logger.debug('[BACKUPS] Remote tree', remote);

Logger.debug('[BACKUPS] Remote tree file', remote.files);

Logger.debug('[BACKUPS] Remote tree folder', remote.folders);

const foldersDiff = FoldersDiffCalculator.calculate(local, remote);

Logger.debug('[BACKUPS] Folders diff', foldersDiff);

const filesDiff = DiffFilesCalculator.calculate(local, remote);

Logger.debug('[BACKUPS] Files diff', filesDiff);

await this.isThereEnoughSpace(filesDiff);

const alreadyBacked =
Expand Down Expand Up @@ -118,41 +131,44 @@ export class Backup {
remote: RemoteTree
) {
Logger.info('[BACKUPS] Backing folders');

Logger.info('[BACKUPS] Folders added', diff.added.length);
Logger.info('[BACKUPS] Folders added', diff.added.length);

for (const localFolder of diff.added) {
Logger.debug('[backupFolders] Remote parent path', localFolder);
await Promise.all(
diff.added.map(async (localFolder) => {
const relativePath = relativeV2(local.root.path, localFolder.path);

const remoteParentPath = relative(local.root.path, localFolder.basedir());
if (relativePath === '/') {
return; // Ignorar la carpeta raíz
}

Logger.debug('[backupFolders] Remote parent path', remoteParentPath);
const parentExists = remote.has(remoteParentPath);
const remoteParentPath = getParentDirectory(
local.root.path,
localFolder.path
);
const parentExists = remote.has(remoteParentPath);

if (!parentExists) {
continue;
}
if (!parentExists) {
return;
}

Logger.debug(
'[backupFolders] get Parent',
relative(local.root.path, localFolder.path)
);
const parent = remote.getParent(
relative(local.root.path, localFolder.path)
);
const parent = remote.getParent(remoteParentPath);
const existingItems = remote.has(relativePath);

// eslint-disable-next-line no-await-in-loop
const folder = await this.simpleFolderCreator.run(
relative(local.root.path, localFolder.path),
parent.id
);
if (existingItems) {
return;
}

remote.addFolder(parent, folder);
const folder = await this.simpleFolderCreator.run(
relativePath,
parent.id
);

this.backed++;
BackupsIPCRenderer.send('backups.progress-update', this.backed);
}
remote.addFolder(parent, folder);

this.backed++;
BackupsIPCRenderer.send('backups.progress-update', this.backed);
})
);
}

private async backupFiles(
Expand Down Expand Up @@ -196,6 +212,8 @@ export class Backup {
);

this.backed += batch.length;

Logger.debug('[Backed]', this.backed);
BackupsIPCRenderer.send('backups.progress-update', this.backed);
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/apps/backups/diff/DiffFilesCalculator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ export class DiffFilesCalculator {
unmodified.push(local);
});

const deleted = remote.files.filter(
(file) => !local.has(path.join(rootPath, file.path) as AbsolutePath)
);
const deleted = remote.files.filter((file) => {
Logger.debug('Checking if file is deleted', file.path);
return !local.has(path.join(rootPath, file.path) as AbsolutePath);
});

const total =
added.length + modified.size + deleted.length + unmodified.length;
Expand Down
26 changes: 24 additions & 2 deletions src/apps/backups/utils/relative.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
import path from 'path';

export function relative(root: string, to: string): string {
const r = path.posix.relative(root, to);
const normalizedTo = to.replace(/^[/\\]+/, '');

return r.startsWith('/') ? r : `/${r}`;
// Unir 'root' con la ruta normalizada
const resolvedPath = path.resolve(root, normalizedTo);

return resolvedPath;
}
export function relativeV2(root: string, to: string): string {
// Obtener la ruta relativa de 'to' respecto a 'root'
const relativePath = path.relative(root, to);

// Asegurar que la ruta empiece con una barra inclinada
return `/${relativePath.replace(/\\/g, '/')}`;
}
export function getParentDirectory(root: string, filePath: string): string {
// Obtener la ruta relativa del archivo en relación al root
const relativePath = path.relative(root, filePath);

// Obtener el directorio padre
const parentDirectory = path.dirname(relativePath);

// Asegurar que la ruta empiece con una barra inclinada
return parentDirectory === '.'
? '/'
: `/${parentDirectory.replace(/\\/g, '/')}`;
}
2 changes: 1 addition & 1 deletion src/apps/renderer/pages/Settings/Backups/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function BackupsSection({
showBackedFolders,
showIssues,
}: BackupsSectionProps) {
const { deviceState } = useContext(DeviceContext);
const { deviceState, current } = useContext(DeviceContext);

return (
<div className={`${active ? 'block' : 'hidden'} w-full`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { LocalFile } from '../../domain/LocalFile';
import { LocalFileHandler } from '../../domain/LocalFileUploader';
import { SimpleFileCreator } from '../../../../virtual-drive/files/application/create/SimpleFileCreator';
import { RemoteTree } from '../../../../virtual-drive/remoteTree/domain/RemoteTree';
import { relative } from '../../../../../apps/backups/utils/relative';
import {
relative,
relativeV2,
} from '../../../../../apps/backups/utils/relative';
import { LocalFileMessenger } from '../../domain/LocalFileMessenger';
import { isFatalError } from '../../../../../apps/shared/issues/SyncErrorCause';
import Logger from 'electron-log';
Expand Down Expand Up @@ -44,7 +47,18 @@ export class FileBatchUploader {

const contentsId = uploadEither.getRight();

const remotePath = relative(localRootPath, localFile.path);
Logger.info('[Local File Uploader] Uploading file', localRootPath);

Logger.info(
'[Local File Uploader] Uploading file',
localFile.path,
'to',
contentsId
);

const remotePath = relativeV2(localRootPath, localFile.path);

Logger.info('Uploading file', localFile.path, 'to', remotePath);

const parent = remoteTree.getParent(remotePath);

Expand All @@ -53,7 +67,7 @@ export class FileBatchUploader {
// eslint-disable-next-line no-await-in-loop
const either = await this.creator.run(
contentsId,
localFile.path,
remotePath,
localFile.size,
parent.id
);
Expand Down
2 changes: 2 additions & 0 deletions src/context/local/localTree/application/LocalTreeBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { LocalTree } from '../domain/LocalTree';
import { LocalFolder } from '../../localFolder/domain/LocalFolder';
import { DriveDesktopError } from '../../../shared/domain/errors/DriveDesktopError';
import { Either, left, right } from '../../../shared/domain/Either';
import Logger from 'electron-log';

@Service()
export default class LocalTreeBuilder {
Expand Down Expand Up @@ -39,6 +40,7 @@ export default class LocalTreeBuilder {
): Promise<Either<DriveDesktopError, LocalTree>> {
const rootEither = await this.generator.root(folder);


if (rootEither.isLeft()) {
return left(rootEither.getLeft());
}
Expand Down
4 changes: 3 additions & 1 deletion src/context/shared/domain/value-objects/Path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ export abstract class Path extends ValueObject<string> {
}

private ensurePathIsPosix(value: string) {
const isPosix = value.indexOf('/') !== -1;
const posixPath = path.posix.normalize(value);

const isPosix = posixPath.indexOf('/') !== -1;

if (!isPosix) {
throw new InvalidArgumentError(`Paths have to be posix, path: ${value}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ export class SimpleFolderCreator {
constructor(private readonly rfs: RemoteFileSystem) {}

async run(path: string, parentId: number): Promise<Folder> {
Logger.debug('Creating folder', path, 'with parent', parentId);
const folderPath = new FolderPath(path);
Logger.debug('Creating folder', folderPath);
const folderParentId = new FolderId(parentId);

const response = await this.rfs.persistv2(folderPath, folderParentId);

Logger.debug('Creating folder', folderPath, 'with parent', folderParentId);

const folder = await response.fold<Promise<Folder | undefined>>(
async (error): Promise<Folder | undefined> => {
Logger.warn('The folder was not been able to create', error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Service } from 'diod';
import { RemoteItemsGenerator } from '../domain/RemoteItemsGenerator';
import { RemoteTree } from '../domain/RemoteTree';
import { Traverser } from './Traverser';
import Logger from 'electron-log';

@Service()
export class RemoteTreeBuilder {
Expand All @@ -17,6 +18,14 @@ export class RemoteTreeBuilder {

const items = await this.remoteItemsGenerator.getAll();

Logger.debug('[REMOTE TREE BUILDER] Items', items.files.length);

Logger.debug('[REMOTE TREE BUILDER] Items', items.files);

Logger.debug('[REMOTE TREE BUILDER] Items', items.folders.length);

Logger.debug('[REMOTE TREE BUILDER] Items', items.folders);

return this.traverser.run(rootFolderId, items);
}
}
2 changes: 2 additions & 0 deletions src/context/virtual-drive/remoteTree/application/Traverser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ export class Traverser {
public run(rootFolderId: number, items: Items): RemoteTree {
const rootFolder = this.createRootFolder(rootFolderId);

Logger.debug('[Traverser] Root folder', rootFolder);

const tree = new RemoteTree(rootFolder);

this.traverse(tree, items, rootFolder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ import { ServerFolder } from '../../../shared/domain/ServerFolder';
export abstract class RemoteItemsGenerator {
abstract getAll(): Promise<{ files: ServerFile[]; folders: ServerFolder[] }>;

// abstract getAllItemsByFolderId(
// folderUid: string
// ): Promise<{ files: ServerFile[]; folders: ServerFolder[] }>;

abstract forceRefresh(): Promise<void>;
}
6 changes: 4 additions & 2 deletions src/context/virtual-drive/remoteTree/domain/RemoteTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { FileNode } from './FileNode';
import { FolderNode } from './FolderNode';
import { Node } from './Node';
import Logger from 'electron-log';

export class RemoteTree {
private tree = new Map<string, Node>();

constructor(rootFolder: Folder) {
const node = FolderNode.createRoot(rootFolder);
Logger.debug('[REMOTE TREE] Creating root node', rootFolder);
this.tree.set('/', node);
}

Expand Down Expand Up @@ -92,7 +94,6 @@ export class RemoteTree {
}

public get(id: string): File | Folder {
Logger.info(`Getting node for id: ${id}`);
const node = this.tree.get(id);

if (!node) {
Expand All @@ -113,10 +114,11 @@ export class RemoteTree {
}

public getParent(id: string): Folder {
Logger.info(`Getting parent for id: ${id}`);
const dirname = path.dirname(id);
Logger.debug('[REMOTE TREE] Getting parent for', id, 'dirname', dirname);
const parentId = dirname === '.' ? path.sep : dirname;

Logger.debug('[REMOTE TREE] Getting parent for', id, 'parentId', parentId);
const element = this.get(parentId);

if (element.isFile()) {
Expand Down
4 changes: 3 additions & 1 deletion src/context/virtual-drive/shared/domain/Path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export abstract class Path extends ValueObject<string> {
}

private ensurePathIsPosix(value: string) {
const isPosix = value.indexOf('/') !== -1;
const posixPath = path.posix.normalize(value);

const isPosix = posixPath.indexOf('/') !== -1;

if (!isPosix) {
throw new InvalidArgumentError(`Paths have to be posix, path: ${value}`);
Expand Down

0 comments on commit f5568c8

Please sign in to comment.