1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-27 10:32:58 +02:00

Desktop, Cli: Fixes #6197: Fixed creation of empty notebooks when importing directory of files (#6274)

This commit is contained in:
Retrove 2022-03-29 00:13:13 +08:00 committed by GitHub
parent a62e1fba96
commit a73d822998
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 4 deletions

View File

@ -1,21 +1,33 @@
import InteropService_Importer_Md from '../../services/interop/InteropService_Importer_Md';
import Note from '../../models/Note';
import { setupDatabaseAndSynchronizer, supportDir, switchClient } from '../../testing/test-utils';
import Folder from '../../models/Folder';
import * as fs from 'fs-extra';
import { createTempDir, setupDatabaseAndSynchronizer, supportDir, switchClient } from '../../testing/test-utils';
import { MarkupToHtml } from '@joplin/renderer';
import { FolderEntity } from '../database/types';
describe('InteropService_Importer_Md: importLocalImages', function() {
describe('InteropService_Importer_Md', function() {
let tempDir: string;
async function importNote(path: string) {
const importer = new InteropService_Importer_Md();
importer.setMetadata({ fileExtensions: ['md', 'html'] });
return await importer.importFile(path, 'notebook');
}
async function importNoteDirectory(path: string) {
const importer = new InteropService_Importer_Md();
importer.setMetadata({ fileExtensions: ['md', 'html'] });
return await importer.importDirectory(path, 'notebook');
}
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
tempDir = await createTempDir();
done();
});
afterEach(async () => {
await fs.remove(tempDir);
});
it('should import linked files and modify tags appropriately', async function() {
const note = await importNote(`${supportDir}/test_notes/md/sample.md`);
@ -117,4 +129,30 @@ describe('InteropService_Importer_Md: importLocalImages', function() {
const preservedAlt = note.body.includes('alt="../../photo.jpg"');
expect(preservedAlt).toBe(true);
});
it('should import non-empty directory', async function() {
await fs.mkdirp(`${tempDir}/non-empty/non-empty`);
await fs.writeFile(`${tempDir}/non-empty/non-empty/sample.md`, '# Sample');
await importNoteDirectory(`${tempDir}/non-empty`);
const allFolders = await Folder.all();
expect(allFolders.map((f: FolderEntity) => f.title).indexOf('non-empty')).toBeGreaterThanOrEqual(0);
});
it('should not import empty directory', async function() {
await fs.mkdirp(`${tempDir}/empty/empty`);
await importNoteDirectory(`${tempDir}/empty`);
const allFolders = await Folder.all();
expect(allFolders.map((f: FolderEntity) => f.title).indexOf('empty')).toBe(-1);
});
it('should import directory with non-empty subdirectory', async function() {
await fs.mkdirp(`${tempDir}/non-empty-subdir/non-empty-subdir/subdir-empty`);
await fs.mkdirp(`${tempDir}/non-empty-subdir/non-empty-subdir/subdir-non-empty`);
await fs.writeFile(`${tempDir}/non-empty-subdir/non-empty-subdir/subdir-non-empty/sample.md`, '# Sample');
await importNoteDirectory(`${tempDir}/non-empty-subdir`);
const allFolders = await Folder.all();
expect(allFolders.map((f: FolderEntity) => f.title).indexOf('non-empty-subdir')).toBeGreaterThanOrEqual(0);
expect(allFolders.map((f: FolderEntity) => f.title).indexOf('subdir-empty')).toBe(-1);
expect(allFolders.map((f: FolderEntity) => f.title).indexOf('subdir-non-empty')).toBeGreaterThanOrEqual(0);
});
});

View File

@ -47,13 +47,16 @@ export default class InteropService_Importer_Md extends InteropService_Importer_
async importDirectory(dirPath: string, parentFolderId: string) {
console.info(`Import: ${dirPath}`);
const supportedFileExtension = this.metadata().fileExtensions;
const stats = await shim.fsDriver().readDirStats(dirPath);
for (let i = 0; i < stats.length; i++) {
const stat = stats[i];
if (stat.isDirectory()) {
if (await this.isDirectoryEmpty(`${dirPath}/${stat.path}`)) {
console.info(`Ignoring empty directory: ${stat.path}`);
continue;
}
const folderTitle = await Folder.findUniqueItemTitle(basename(stat.path));
const folder = await Folder.save({ title: folderTitle, parent_id: parentFolderId });
await this.importDirectory(`${dirPath}/${basename(stat.path)}`, folder.id);
@ -63,6 +66,24 @@ export default class InteropService_Importer_Md extends InteropService_Importer_
}
}
private async isDirectoryEmpty(dirPath: string) {
const supportedFileExtension = this.metadata().fileExtensions;
const innerStats = await shim.fsDriver().readDirStats(dirPath);
for (let i = 0; i < innerStats.length; i++) {
const innerStat = innerStats[i];
if (innerStat.isDirectory()) {
if (!(await this.isDirectoryEmpty(`${dirPath}/${innerStat.path}`))) {
return false;
}
} else if (supportedFileExtension.indexOf(fileExtension(innerStat.path).toLowerCase()) >= 0) {
return false;
}
}
return true;
}
private trimAnchorLink(link: string) {
if (link.indexOf('#') <= 0) return link;