mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
progress of tar import through WS
This commit is contained in:
parent
51175e3676
commit
cde68abec9
@ -2,13 +2,20 @@ import treeService from '../services/tree.js';
|
|||||||
import treeUtils from "../services/tree_utils.js";
|
import treeUtils from "../services/tree_utils.js";
|
||||||
import server from "../services/server.js";
|
import server from "../services/server.js";
|
||||||
import infoService from "../services/info.js";
|
import infoService from "../services/info.js";
|
||||||
|
import messagingService from "../services/messaging.js";
|
||||||
|
|
||||||
const $dialog = $("#import-dialog");
|
const $dialog = $("#import-dialog");
|
||||||
const $form = $("#import-form");
|
const $form = $("#import-form");
|
||||||
const $noteTitle = $dialog.find(".note-title");
|
const $noteTitle = $dialog.find(".note-title");
|
||||||
const $fileUploadInput = $("#import-file-upload-input");
|
const $fileUploadInput = $("#import-file-upload-input");
|
||||||
|
const $importNoteCountWrapper = $("#import-note-count-wrapper");
|
||||||
|
const $importNoteCount = $("#import-note-count");
|
||||||
|
|
||||||
async function showDialog() {
|
async function showDialog() {
|
||||||
|
$importNoteCountWrapper.hide();
|
||||||
|
$importNoteCount.text('0');
|
||||||
|
$fileUploadInput.val('');
|
||||||
|
|
||||||
glob.activeDialog = $dialog;
|
glob.activeDialog = $dialog;
|
||||||
|
|
||||||
const currentNode = treeService.getCurrentNode();
|
const currentNode = treeService.getCurrentNode();
|
||||||
@ -29,10 +36,6 @@ function importIntoNote(importNoteId) {
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('upload', $fileUploadInput[0].files[0]);
|
formData.append('upload', $fileUploadInput[0].files[0]);
|
||||||
|
|
||||||
// this is done to reset the field otherwise triggering import same file again would not work
|
|
||||||
// https://github.com/zadam/trilium/issues/388
|
|
||||||
$fileUploadInput.val('');
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: baseApiUrl + 'notes/' + importNoteId + '/import',
|
url: baseApiUrl + 'notes/' + importNoteId + '/import',
|
||||||
headers: server.getHeaders(),
|
headers: server.getHeaders(),
|
||||||
@ -46,7 +49,7 @@ function importIntoNote(importNoteId) {
|
|||||||
.done(async note => {
|
.done(async note => {
|
||||||
$dialog.modal('hide');
|
$dialog.modal('hide');
|
||||||
|
|
||||||
infoService.showMessage("Import finished successfully.")
|
infoService.showMessage("Import finished successfully.");
|
||||||
|
|
||||||
await treeService.reload();
|
await treeService.reload();
|
||||||
|
|
||||||
@ -58,6 +61,14 @@ function importIntoNote(importNoteId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messagingService.subscribeToMessages(message => {
|
||||||
|
if (message.type === 'importNoteCount') {
|
||||||
|
$importNoteCountWrapper.show();
|
||||||
|
|
||||||
|
$importNoteCount.text(message.count);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
showDialog
|
showDialog
|
||||||
}
|
}
|
@ -38,7 +38,7 @@ function handleMessage(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message.type === 'sync') {
|
if (message.type === 'sync') {
|
||||||
lastPingTs = new Date().getTime();
|
lastPingTs = Date.now();
|
||||||
|
|
||||||
if (message.data.length > 0) {
|
if (message.data.length > 0) {
|
||||||
console.debug(utils.now(), "Sync data: ", message.data);
|
console.debug(utils.now(), "Sync data: ", message.data);
|
||||||
@ -81,10 +81,10 @@ setTimeout(() => {
|
|||||||
ws = connectWebSocket();
|
ws = connectWebSocket();
|
||||||
|
|
||||||
lastSyncId = glob.maxSyncIdAtLoad;
|
lastSyncId = glob.maxSyncIdAtLoad;
|
||||||
lastPingTs = new Date().getTime();
|
lastPingTs = Date.now();
|
||||||
|
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
if (new Date().getTime() - lastPingTs > 30000) {
|
if (Date.now() - lastPingTs > 30000) {
|
||||||
console.log("Lost connection to server");
|
console.log("Lost connection to server");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ let protectedSessionId = null;
|
|||||||
optionsInitService.optionsReady.then(options => protectedSessionTimeout = options.protectedSessionTimeout);
|
optionsInitService.optionsReady.then(options => protectedSessionTimeout = options.protectedSessionTimeout);
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (lastProtectedSessionOperationDate !== null && new Date().getTime() - lastProtectedSessionOperationDate.getTime() > protectedSessionTimeout * 1000) {
|
if (lastProtectedSessionOperationDate !== null && Date.now() - lastProtectedSessionOperationDate.getTime() > protectedSessionTimeout * 1000) {
|
||||||
resetProtectedSession();
|
resetProtectedSession();
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
@ -77,7 +77,7 @@ async function stopWatch(what, func) {
|
|||||||
|
|
||||||
const ret = await func();
|
const ret = await func();
|
||||||
|
|
||||||
const tookMs = new Date().getTime() - start.getTime();
|
const tookMs = Date.now() - start.getTime();
|
||||||
|
|
||||||
console.log(`${what} took ${tookMs}ms`);
|
console.log(`${what} took ${tookMs}ms`);
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ async function runChecks() {
|
|||||||
|
|
||||||
await runAllChecks();
|
await runAllChecks();
|
||||||
|
|
||||||
elapsedTimeMs = new Date().getTime() - startTime.getTime();
|
elapsedTimeMs = Date.now() - startTime.getTime();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fixedIssues) {
|
if (fixedIssues) {
|
||||||
|
@ -42,7 +42,7 @@ async function getHashes() {
|
|||||||
links: await getHash(Link)
|
links: await getHash(Link)
|
||||||
};
|
};
|
||||||
|
|
||||||
const elapseTimeMs = new Date().getTime() - startTime.getTime();
|
const elapseTimeMs = Date.now() - startTime.getTime();
|
||||||
|
|
||||||
log.info(`Content hash computation took ${elapseTimeMs}ms`);
|
log.info(`Content hash computation took ${elapseTimeMs}ms`);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ const utils = require('../../services/utils');
|
|||||||
const log = require('../../services/log');
|
const log = require('../../services/log');
|
||||||
const repository = require('../../services/repository');
|
const repository = require('../../services/repository');
|
||||||
const noteService = require('../../services/notes');
|
const noteService = require('../../services/notes');
|
||||||
|
const messagingService = require('../../services/messaging');
|
||||||
const Branch = require('../../entities/branch');
|
const Branch = require('../../entities/branch');
|
||||||
const tar = require('tar-stream');
|
const tar = require('tar-stream');
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
@ -13,7 +14,12 @@ const path = require('path');
|
|||||||
const commonmark = require('commonmark');
|
const commonmark = require('commonmark');
|
||||||
const mimeTypes = require('mime-types');
|
const mimeTypes = require('mime-types');
|
||||||
|
|
||||||
|
let importNoteCount;
|
||||||
|
let lastSentCountTs = Date.now();
|
||||||
|
|
||||||
async function importTar(fileBuffer, importRootNote) {
|
async function importTar(fileBuffer, importRootNote) {
|
||||||
|
importNoteCount = 0;
|
||||||
|
|
||||||
// maps from original noteId (in tar file) to newly generated noteId
|
// maps from original noteId (in tar file) to newly generated noteId
|
||||||
const noteIdMap = {};
|
const noteIdMap = {};
|
||||||
const attributes = [];
|
const attributes = [];
|
||||||
@ -287,7 +293,7 @@ async function importTar(fileBuffer, importRootNote) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return path without leading or trailing slash and backslashes converted to forward ones*/
|
/** @return {string} path without leading or trailing slash and backslashes converted to forward ones*/
|
||||||
function normalizeFilePath(filePath) {
|
function normalizeFilePath(filePath) {
|
||||||
filePath = filePath.replace(/\\/g, "/");
|
filePath = filePath.replace(/\\/g, "/");
|
||||||
|
|
||||||
@ -314,7 +320,7 @@ async function importTar(fileBuffer, importRootNote) {
|
|||||||
// call next when you are done with this entry
|
// call next when you are done with this entry
|
||||||
|
|
||||||
stream.on('end', async function() {
|
stream.on('end', async function() {
|
||||||
let filePath = normalizeFilePath(header.name);
|
const filePath = normalizeFilePath(header.name);
|
||||||
|
|
||||||
const content = Buffer.concat(chunks);
|
const content = Buffer.concat(chunks);
|
||||||
|
|
||||||
@ -331,6 +337,14 @@ async function importTar(fileBuffer, importRootNote) {
|
|||||||
log.info("Ignoring tar import entry with type " + header.type);
|
log.info("Ignoring tar import entry with type " + header.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
importNoteCount++;
|
||||||
|
|
||||||
|
if (Date.now() - lastSentCountTs >= 1000) {
|
||||||
|
lastSentCountTs = Date.now();
|
||||||
|
|
||||||
|
messagingService.sendMessageToAllClients({ type: 'importNoteCount', count: importNoteCount });
|
||||||
|
}
|
||||||
|
|
||||||
next(); // ready for next entry
|
next(); // ready for next entry
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ async function deleteNote(branch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function cleanupDeletedNotes() {
|
async function cleanupDeletedNotes() {
|
||||||
const cutoffDate = new Date(new Date().getTime() - 48 * 3600 * 1000);
|
const cutoffDate = new Date(Date.now() - 48 * 3600 * 1000);
|
||||||
|
|
||||||
// it's better to not use repository for this because it will complain about saving protected notes
|
// it's better to not use repository for this because it will complain about saving protected notes
|
||||||
// out of protected session
|
// out of protected session
|
||||||
|
@ -132,7 +132,7 @@ async function pullSync(syncContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.info("Pulled " + rows.length + " changes from " + changesUri + " in "
|
log.info("Pulled " + rows.length + " changes from " + changesUri + " in "
|
||||||
+ (new Date().getTime() - startDate.getTime()) + "ms");
|
+ (Date.now() - startDate.getTime()) + "ms");
|
||||||
|
|
||||||
for (const {sync, entity} of rows) {
|
for (const {sync, entity} of rows) {
|
||||||
if (!sourceIdService.isLocalSourceId(sync.sourceId)) {
|
if (!sourceIdService.isLocalSourceId(sync.sourceId)) {
|
||||||
@ -194,7 +194,7 @@ async function pushSync(syncContext) {
|
|||||||
entities: syncRecords
|
entities: syncRecords
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info(`Pushing ${syncRecords.length} syncs in ` + (new Date().getTime() - startDate.getTime()) + "ms");
|
log.info(`Pushing ${syncRecords.length} syncs in ` + (Date.now() - startDate.getTime()) + "ms");
|
||||||
|
|
||||||
lastSyncedPush = syncRecords[syncRecords.length - 1].sync.id;
|
lastSyncedPush = syncRecords[syncRecords.length - 1].sync.id;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ async function stopWatch(what, func) {
|
|||||||
|
|
||||||
const ret = await func();
|
const ret = await func();
|
||||||
|
|
||||||
const tookMs = new Date().getTime() - start.getTime();
|
const tookMs = Date.now() - start.getTime();
|
||||||
|
|
||||||
console.log(`${what} took ${tookMs}ms`);
|
console.log(`${what} took ${tookMs}ms`);
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
Trilium <code>.tar</code> export files can contain executable scripts which may contain harmful behavior. Safe import will deactivate automatic execution of all imported scripts. Uncheck "Safe import" only if the imported tar archive is supposed to contain executable scripts and you completely trust the contents of the import file.
|
Trilium <code>.tar</code> export files can contain executable scripts which may contain harmful behavior. Safe import will deactivate automatic execution of all imported scripts. Uncheck "Safe import" only if the imported tar archive is supposed to contain executable scripts and you completely trust the contents of the import file.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="import-note-count-wrapper">
|
||||||
|
<strong>Imported notes:</strong> <span id="import-note-count"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-primary">Import</button>
|
<button class="btn btn-primary">Import</button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user