mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
refactoring + uploading attachments WIP
This commit is contained in:
parent
b05ce12e7b
commit
626af84f42
@ -3,6 +3,7 @@
|
|||||||
const sql = require("../services/sql");
|
const sql = require("../services/sql");
|
||||||
const NoteSet = require("../services/search/note_set");
|
const NoteSet = require("../services/search/note_set");
|
||||||
const BAttachment = require("./entities/battachment.js");
|
const BAttachment = require("./entities/battachment.js");
|
||||||
|
const NotFoundError = require("../errors/not_found_error.js");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Becca is a backend cache of all notes, branches and attributes. There's a similar frontend cache Froca.
|
* Becca is a backend cache of all notes, branches and attributes. There's a similar frontend cache Froca.
|
||||||
@ -78,6 +79,16 @@ class Becca {
|
|||||||
return this.notes[noteId];
|
return this.notes[noteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @returns {BNote|null} */
|
||||||
|
getNoteOrThrow(noteId) {
|
||||||
|
const note = this.notes[noteId];
|
||||||
|
if (!note) {
|
||||||
|
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
/** @returns {BNote[]} */
|
/** @returns {BNote[]} */
|
||||||
getNotes(noteIds, ignoreMissing = false) {
|
getNotes(noteIds, ignoreMissing = false) {
|
||||||
const filteredNotes = [];
|
const filteredNotes = [];
|
||||||
@ -104,11 +115,30 @@ class Becca {
|
|||||||
return this.branches[branchId];
|
return this.branches[branchId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @returns {BBranch|null} */
|
||||||
|
getBranchOrThrow(branchId) {
|
||||||
|
const branch = this.getBranch(branchId);
|
||||||
|
if (!branch) {
|
||||||
|
throw new NotFoundError(`Branch '${branchId}' was not found in becca.`);
|
||||||
|
}
|
||||||
|
return branch;
|
||||||
|
}
|
||||||
|
|
||||||
/** @returns {BAttribute|null} */
|
/** @returns {BAttribute|null} */
|
||||||
getAttribute(attributeId) {
|
getAttribute(attributeId) {
|
||||||
return this.attributes[attributeId];
|
return this.attributes[attributeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @returns {BAttribute} */
|
||||||
|
getAttributeOrThrow(attributeId) {
|
||||||
|
const attribute = this.getAttribute(attributeId);
|
||||||
|
if (!attribute) {
|
||||||
|
throw new NotFoundError(`Attribute '${attributeId}' does not exist.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
/** @returns {BBranch|null} */
|
/** @returns {BBranch|null} */
|
||||||
getBranchFromChildAndParent(childNoteId, parentNoteId) {
|
getBranchFromChildAndParent(childNoteId, parentNoteId) {
|
||||||
return this.childParentToBranch[`${childNoteId}-${parentNoteId}`];
|
return this.childParentToBranch[`${childNoteId}-${parentNoteId}`];
|
||||||
@ -130,6 +160,15 @@ class Becca {
|
|||||||
return row ? new BAttachment(row) : null;
|
return row ? new BAttachment(row) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @returns {BAttachment} */
|
||||||
|
getAttachmentOrThrow(attachmentId) {
|
||||||
|
const attachment = this.getAttachment(attachmentId);
|
||||||
|
if (!attachment) {
|
||||||
|
throw new NotFoundError(`Attachment '${attachmentId}' has not been found.`);
|
||||||
|
}
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
|
|
||||||
/** @returns {BAttachment[]} */
|
/** @returns {BAttachment[]} */
|
||||||
getAttachments(attachmentIds) {
|
getAttachments(attachmentIds) {
|
||||||
const BAttachment = require("./entities/battachment"); // avoiding circular dependency problems
|
const BAttachment = require("./entities/battachment"); // avoiding circular dependency problems
|
||||||
|
@ -27,7 +27,7 @@ function load() {
|
|||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
becca.reset();
|
becca.reset();
|
||||||
|
|
||||||
// using raw query and passing arrays to avoid allocating new objects
|
// using a raw query and passing arrays to avoid allocating new objects,
|
||||||
// this is worth it for becca load since it happens every run and blocks the app until finished
|
// this is worth it for becca load since it happens every run and blocks the app until finished
|
||||||
|
|
||||||
for (const row of sql.getRawRows(`SELECT noteId, title, type, mime, isProtected, blobId, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes WHERE isDeleted = 0`)) {
|
for (const row of sql.getRawRows(`SELECT noteId, title, type, mime, isProtected, blobId, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes WHERE isDeleted = 0`)) {
|
||||||
|
@ -11,7 +11,6 @@ const BAttachment = require("./battachment");
|
|||||||
const TaskContext = require("../../services/task_context");
|
const TaskContext = require("../../services/task_context");
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
const utc = require('dayjs/plugin/utc');
|
const utc = require('dayjs/plugin/utc');
|
||||||
const NotFoundError = require("../../errors/not_found_error.js");
|
|
||||||
const eventService = require("../../services/events.js");
|
const eventService = require("../../services/events.js");
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
||||||
@ -1622,11 +1621,7 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
let attachment;
|
let attachment;
|
||||||
|
|
||||||
if (attachmentId) {
|
if (attachmentId) {
|
||||||
attachment = this.becca.getAttachment(attachmentId);
|
attachment = this.becca.getAttachmentOrThrow(attachmentId);
|
||||||
|
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${attachmentId}' has not been found.`);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
attachment = new BAttachment({
|
attachment = new BAttachment({
|
||||||
parentId: this.noteId,
|
parentId: this.noteId,
|
||||||
|
@ -4,7 +4,11 @@ import ws from "./ws.js";
|
|||||||
import utils from "./utils.js";
|
import utils from "./utils.js";
|
||||||
import appContext from "../components/app_context.js";
|
import appContext from "../components/app_context.js";
|
||||||
|
|
||||||
export async function uploadFiles(parentNoteId, files, options) {
|
export async function uploadFiles(entityType, parentNoteId, files, options) {
|
||||||
|
if (!['notes', 'attachments'].includes(entityType)) {
|
||||||
|
throw new Error(`Unrecognized import entity type '${entityType}'.`);
|
||||||
|
}
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -25,7 +29,7 @@ export async function uploadFiles(parentNoteId, files, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await $.ajax({
|
await $.ajax({
|
||||||
url: `${window.glob.baseApiUrl}notes/${parentNoteId}/import`,
|
url: `${window.glob.baseApiUrl}notes/${parentNoteId}/${entityType}-import`,
|
||||||
headers: await server.getHeaders(),
|
headers: await server.getHeaders(),
|
||||||
data: formData,
|
data: formData,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
@ -154,6 +154,6 @@ export default class ImportDialog extends BasicWidget {
|
|||||||
|
|
||||||
this.$widget.modal('hide');
|
this.$widget.modal('hide');
|
||||||
|
|
||||||
await importService.uploadFiles(parentNoteId, files, options);
|
await importService.uploadFiles('notes', parentNoteId, files, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
107
src/public/app/widgets/dialogs/upload_attachments.js
Normal file
107
src/public/app/widgets/dialogs/upload_attachments.js
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import utils from '../../services/utils.js';
|
||||||
|
import treeService from "../../services/tree.js";
|
||||||
|
import importService from "../../services/import.js";
|
||||||
|
import options from "../../services/options.js";
|
||||||
|
import BasicWidget from "../basic_widget.js";
|
||||||
|
|
||||||
|
const TPL = `
|
||||||
|
<div class="upload-attachments-dialog modal fade mx-auto" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Import into note</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form class="upload-attachment-form">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="upload-attachment-file-upload-input"><strong>Choose files</strong></label>
|
||||||
|
|
||||||
|
<input type="file" class="upload-attachment-file-upload-input form-control-file" multiple />
|
||||||
|
|
||||||
|
<p>Content of the file will be imported as child note(s) into <strong class="upload-attachment-note-title"></strong>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<strong>Options:</strong>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label data-toggle="tooltip" title="<p>If you check this option, Trilium will attempt to shrink the uploaded images by scaling and optimization which may affect the perceived image quality. If unchecked, images will be uploaded without changes.</p>">
|
||||||
|
<input class="shrink-images-checkbox" value="1" type="checkbox" checked> <span>Shrink images</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="upload-attachment-button btn btn-primary">Upload</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
export default class UploadAttachmentsDialog extends BasicWidget {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.parentNoteId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
doRender() {
|
||||||
|
this.$widget = $(TPL);
|
||||||
|
this.$form = this.$widget.find(".upload-attachment-form");
|
||||||
|
this.$noteTitle = this.$widget.find(".upload-attachment-note-title");
|
||||||
|
this.$fileUploadInput = this.$widget.find(".upload-attachment-file-upload-input");
|
||||||
|
this.$uploadButton = this.$widget.find(".upload-attachment-button");
|
||||||
|
this.$shrinkImagesCheckbox = this.$widget.find(".shrink-images-checkbox");
|
||||||
|
|
||||||
|
this.$form.on('submit', () => {
|
||||||
|
// disabling so that import is not triggered again.
|
||||||
|
this.$uploadButton.attr("disabled", "disabled");
|
||||||
|
|
||||||
|
this.uploadAttachments(this.parentNoteId);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$fileUploadInput.on('change', () => {
|
||||||
|
if (this.$fileUploadInput.val()) {
|
||||||
|
this.$uploadButton.removeAttr("disabled");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.$uploadButton.attr("disabled", "disabled");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$widget.find('[data-toggle="tooltip"]').tooltip({
|
||||||
|
html: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async showUploadAttachmentsDialogEvent({noteId}) {
|
||||||
|
this.parentNoteId = noteId;
|
||||||
|
|
||||||
|
this.$fileUploadInput.val('').trigger('change'); // to trigger upload button disabling listener below
|
||||||
|
this.$shrinkImagesCheckbox.prop("checked", options.is('compressImages'));
|
||||||
|
|
||||||
|
this.$noteTitle.text(await treeService.getNoteTitle(this.parentNoteId));
|
||||||
|
|
||||||
|
utils.openDialog(this.$widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
async uploadAttachments(parentNoteId) {
|
||||||
|
const files = Array.from(this.$fileUploadInput[0].files); // shallow copy since we're resetting the upload button below
|
||||||
|
|
||||||
|
const boolToString = $el => $el.is(":checked") ? "true" : "false";
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
shrinkImages: boolToString(this.$shrinkImagesCheckbox),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$widget.modal('hide');
|
||||||
|
|
||||||
|
await importService.uploadFiles('attachments', parentNoteId, files, options);
|
||||||
|
}
|
||||||
|
}
|
@ -116,7 +116,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
const importService = await import('../services/import.js');
|
const importService = await import('../services/import.js');
|
||||||
|
|
||||||
importService.uploadFiles(activeNote.noteId, files, {
|
importService.uploadFiles('notes', activeNote.noteId, files, {
|
||||||
safeImport: true,
|
safeImport: true,
|
||||||
shrinkImages: true,
|
shrinkImages: true,
|
||||||
textImportedAsText: true,
|
textImportedAsText: true,
|
||||||
|
@ -442,7 +442,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
const importService = await import('../services/import.js');
|
const importService = await import('../services/import.js');
|
||||||
|
|
||||||
importService.uploadFiles(node.data.noteId, files, {
|
importService.uploadFiles('notes', node.data.noteId, files, {
|
||||||
safeImport: true,
|
safeImport: true,
|
||||||
shrinkImages: true,
|
shrinkImages: true,
|
||||||
textImportedAsText: true,
|
textImportedAsText: true,
|
||||||
|
@ -37,7 +37,10 @@ export default class AttachmentListTypeWidget extends TypeWidget {
|
|||||||
async doRefresh(note) {
|
async doRefresh(note) {
|
||||||
this.$linksWrapper.append(
|
this.$linksWrapper.append(
|
||||||
"Owning note: ",
|
"Owning note: ",
|
||||||
await linkService.createNoteLink(this.noteId)
|
await linkService.createNoteLink(this.noteId),
|
||||||
|
$('<button class="btn btn-sm">')
|
||||||
|
.text("Upload attachments")
|
||||||
|
.on('click', () => this.triggerCommand("showUploadAttachmentsDialog", {noteId: this.noteId}))
|
||||||
);
|
);
|
||||||
|
|
||||||
this.$list.empty();
|
this.$list.empty();
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
const utils = require("../../services/utils");
|
const utils = require("../../services/utils");
|
||||||
const blobService = require("../../services/blob.js");
|
const blobService = require("../../services/blob.js");
|
||||||
|
|
||||||
@ -11,13 +10,7 @@ function getAttachmentBlob(req) {
|
|||||||
|
|
||||||
function getAttachments(req) {
|
function getAttachments(req) {
|
||||||
const includeContent = req.query.includeContent === 'true';
|
const includeContent = req.query.includeContent === 'true';
|
||||||
const {noteId} = req.params;
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return note.getAttachments()
|
return note.getAttachments()
|
||||||
.map(attachment => processAttachment(attachment, includeContent));
|
.map(attachment => processAttachment(attachment, includeContent));
|
||||||
@ -27,11 +20,7 @@ function getAttachment(req) {
|
|||||||
const includeContent = req.query.includeContent === 'true';
|
const includeContent = req.query.includeContent === 'true';
|
||||||
const {attachmentId} = req.params;
|
const {attachmentId} = req.params;
|
||||||
|
|
||||||
const attachment = becca.getAttachment(attachmentId);
|
const attachment = becca.getAttachmentOrThrow(attachmentId);
|
||||||
|
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${attachmentId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return processAttachment(attachment, includeContent);
|
return processAttachment(attachment, includeContent);
|
||||||
}
|
}
|
||||||
@ -62,12 +51,7 @@ function saveAttachment(req) {
|
|||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
const {attachmentId, role, mime, title, content} = req.body;
|
const {attachmentId, role, mime, title, content} = req.body;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
note.saveAttachment({attachmentId, role, mime, title, content});
|
note.saveAttachment({attachmentId, role, mime, title, content});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,12 +68,7 @@ function deleteAttachment(req) {
|
|||||||
function convertAttachmentToNote(req) {
|
function convertAttachmentToNote(req) {
|
||||||
const {attachmentId} = req.params;
|
const {attachmentId} = req.params;
|
||||||
|
|
||||||
const attachment = becca.getAttachment(attachmentId);
|
const attachment = becca.getAttachmentOrThrow(attachmentId);
|
||||||
|
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${attachmentId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return attachment.convertToNote();
|
return attachment.convertToNote();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ const attributeService = require('../../services/attributes');
|
|||||||
const BAttribute = require('../../becca/entities/battribute');
|
const BAttribute = require('../../becca/entities/battribute');
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const ValidationError = require("../../errors/validation_error");
|
const ValidationError = require("../../errors/validation_error");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
function getEffectiveNoteAttributes(req) {
|
function getEffectiveNoteAttributes(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNote(req.params.noteId);
|
||||||
@ -20,11 +19,7 @@ function updateNoteAttribute(req) {
|
|||||||
|
|
||||||
let attribute;
|
let attribute;
|
||||||
if (body.attributeId) {
|
if (body.attributeId) {
|
||||||
attribute = becca.getAttribute(body.attributeId);
|
attribute = becca.getAttributeOrThrow(body.attributeId);
|
||||||
|
|
||||||
if (!attribute) {
|
|
||||||
throw new NotFoundError(`Attribute '${body.attributeId}' does not exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute.noteId !== noteId) {
|
if (attribute.noteId !== noteId) {
|
||||||
throw new ValidationError(`Attribute '${body.attributeId}' is not owned by ${noteId}`);
|
throw new ValidationError(`Attribute '${body.attributeId}' is not owned by ${noteId}`);
|
||||||
|
@ -10,7 +10,6 @@ const TaskContext = require('../../services/task_context');
|
|||||||
const branchService = require("../../services/branches");
|
const branchService = require("../../services/branches");
|
||||||
const log = require("../../services/log");
|
const log = require("../../services/log");
|
||||||
const ValidationError = require("../../errors/validation_error");
|
const ValidationError = require("../../errors/validation_error");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code in this file deals with moving and cloning branches. The relationship between note and parent note is unique
|
* Code in this file deals with moving and cloning branches. The relationship between note and parent note is unique
|
||||||
@ -33,16 +32,8 @@ function moveBranchToParent(req) {
|
|||||||
function moveBranchBeforeNote(req) {
|
function moveBranchBeforeNote(req) {
|
||||||
const {branchId, beforeBranchId} = req.params;
|
const {branchId, beforeBranchId} = req.params;
|
||||||
|
|
||||||
const branchToMove = becca.getBranch(branchId);
|
const branchToMove = becca.getBranchOrThrow(branchId);
|
||||||
const beforeBranch = becca.getBranch(beforeBranchId);
|
const beforeBranch = becca.getBranchOrThrow(beforeBranchId);
|
||||||
|
|
||||||
if (!branchToMove) {
|
|
||||||
throw new NotFoundError(`Can't find branch '${branchId}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!beforeBranch) {
|
|
||||||
throw new NotFoundError(`Can't find branch '${beforeBranchId}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const validationResult = treeService.validateParentChild(beforeBranch.parentNoteId, branchToMove.noteId, branchId);
|
const validationResult = treeService.validateParentChild(beforeBranch.parentNoteId, branchToMove.noteId, branchId);
|
||||||
|
|
||||||
@ -192,11 +183,7 @@ function setExpandedForSubtree(req) {
|
|||||||
function deleteBranch(req) {
|
function deleteBranch(req) {
|
||||||
const last = req.query.last === 'true';
|
const last = req.query.last === 'true';
|
||||||
const eraseNotes = req.query.eraseNotes === 'true';
|
const eraseNotes = req.query.eraseNotes === 'true';
|
||||||
const branch = becca.getBranch(req.params.branchId);
|
const branch = becca.getBranchOrThrow(req.params.branchId);
|
||||||
|
|
||||||
if (!branch) {
|
|
||||||
throw new NotFoundError(`Branch '${req.params.branchId}' not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const taskContext = TaskContext.getInstance(req.query.taskId, 'delete-notes');
|
const taskContext = TaskContext.getInstance(req.query.taskId, 'delete-notes');
|
||||||
|
|
||||||
|
@ -10,14 +10,10 @@ const { Readable } = require('stream');
|
|||||||
const chokidar = require('chokidar');
|
const chokidar = require('chokidar');
|
||||||
const ws = require('../../services/ws');
|
const ws = require('../../services/ws');
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
const ValidationError = require("../../errors/validation_error.js");
|
const ValidationError = require("../../errors/validation_error.js");
|
||||||
|
|
||||||
function updateFile(req) {
|
function updateFile(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = req.file;
|
const file = req.file;
|
||||||
note.saveNoteRevision();
|
note.saveNoteRevision();
|
||||||
@ -37,11 +33,7 @@ function updateFile(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateAttachment(req) {
|
function updateAttachment(req) {
|
||||||
const attachment = becca.getAttachment(req.params.attachmentId);
|
const attachment = becca.getAttachmentOrThrow(req.params.attachmentId);
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${req.params.attachmentId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = req.file;
|
const file = req.file;
|
||||||
attachment.getNote().saveNoteRevision();
|
attachment.getNote().saveNoteRevision();
|
||||||
|
|
||||||
@ -107,20 +99,14 @@ const openAttachment = (req, res) => downloadAttachmentInt(req.params.attachment
|
|||||||
|
|
||||||
function fileContentProvider(req) {
|
function fileContentProvider(req) {
|
||||||
// Read the file name from route params.
|
// Read the file name from route params.
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return streamContent(note.getContent(), note.getFileName(), note.mime);
|
return streamContent(note.getContent(), note.getFileName(), note.mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
function attachmentContentProvider(req) {
|
function attachmentContentProvider(req) {
|
||||||
// Read the file name from route params.
|
// Read the file name from route params.
|
||||||
const attachment = becca.getAttachment(req.params.attachmentId);
|
const attachment = becca.getAttachmentOrThrow(req.params.attachmentId);
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${req.params.attachmentId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return streamContent(attachment.getContent(), attachment.getFileName(), attachment.mime);
|
return streamContent(attachment.getContent(), attachment.getFileName(), attachment.mime);
|
||||||
}
|
}
|
||||||
@ -152,11 +138,7 @@ function streamContent(content, fileName, mimeType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveNoteToTmpDir(req) {
|
function saveNoteToTmpDir(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileName = note.getFileName();
|
const fileName = note.getFileName();
|
||||||
const content = note.getContent();
|
const content = note.getContent();
|
||||||
|
|
||||||
@ -164,11 +146,7 @@ function saveNoteToTmpDir(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveAttachmentToTmpDir(req) {
|
function saveAttachmentToTmpDir(req) {
|
||||||
const attachment = becca.getAttachment(req.params.attachmentId);
|
const attachment = becca.getAttachmentOrThrow(req.params.attachmentId);
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${req.params.attachmentId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileName = attachment.getFileName();
|
const fileName = attachment.getFileName();
|
||||||
const content = attachment.getContent();
|
const content = attachment.getContent();
|
||||||
|
|
||||||
@ -204,11 +182,7 @@ function uploadModifiedFileToNote(req) {
|
|||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const {filePath} = req.body;
|
const {filePath} = req.body;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' has not been found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`Updating note '${noteId}' with content from '${filePath}'`);
|
log.info(`Updating note '${noteId}' with content from '${filePath}'`);
|
||||||
|
|
||||||
@ -227,11 +201,7 @@ function uploadModifiedFileToAttachment(req) {
|
|||||||
const {attachmentId} = req.params;
|
const {attachmentId} = req.params;
|
||||||
const {filePath} = req.body;
|
const {filePath} = req.body;
|
||||||
|
|
||||||
const attachment = becca.getAttachment(attachmentId);
|
const attachment = becca.getAttachmentOrThrow(attachmentId);
|
||||||
|
|
||||||
if (!attachment) {
|
|
||||||
throw new NotFoundError(`Attachment '${attachmentId}' has not been found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`Updating attachment '${attachmentId}' with content from '${filePath}'`);
|
log.info(`Updating attachment '${attachmentId}' with content from '${filePath}'`);
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ const becca = require('../../becca/becca');
|
|||||||
const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
|
const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const ValidationError = require("../../errors/validation_error");
|
const ValidationError = require("../../errors/validation_error");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
function returnImage(req, res) {
|
function returnImage(req, res) {
|
||||||
const image = becca.getNote(req.params.noteId);
|
const image = becca.getNote(req.params.noteId);
|
||||||
@ -64,11 +63,7 @@ function uploadImage(req) {
|
|||||||
const {noteId} = req.query;
|
const {noteId} = req.query;
|
||||||
const {file} = req;
|
const {file} = req;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!["image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) {
|
if (!["image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) {
|
||||||
throw new ValidationError(`Unknown image type '${file.mimetype}'`);
|
throw new ValidationError(`Unknown image type '${file.mimetype}'`);
|
||||||
@ -86,11 +81,7 @@ function updateImage(req) {
|
|||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
const {file} = req;
|
const {file} = req;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) {
|
if (!["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"].includes(file.mimetype)) {
|
||||||
return {
|
return {
|
||||||
|
@ -11,9 +11,8 @@ const beccaLoader = require('../../becca/becca_loader');
|
|||||||
const log = require('../../services/log');
|
const log = require('../../services/log');
|
||||||
const TaskContext = require('../../services/task_context');
|
const TaskContext = require('../../services/task_context');
|
||||||
const ValidationError = require("../../errors/validation_error");
|
const ValidationError = require("../../errors/validation_error");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
async function importToBranch(req) {
|
async function importNotesToBranch(req) {
|
||||||
const {parentNoteId} = req.params;
|
const {parentNoteId} = req.params;
|
||||||
const {taskId, last} = req.body;
|
const {taskId, last} = req.body;
|
||||||
|
|
||||||
@ -32,11 +31,7 @@ async function importToBranch(req) {
|
|||||||
throw new ValidationError("No file has been uploaded");
|
throw new ValidationError("No file has been uploaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentNote = becca.getNote(parentNoteId);
|
const parentNote = becca.getNoteOrThrow(parentNoteId);
|
||||||
|
|
||||||
if (!parentNote) {
|
|
||||||
throw new NotFoundError(`Note '${parentNoteId}' doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const extension = path.extname(file.originalname).toLowerCase();
|
const extension = path.extname(file.originalname).toLowerCase();
|
||||||
|
|
||||||
@ -79,14 +74,68 @@ async function importToBranch(req) {
|
|||||||
}), 1000);
|
}), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// import has deactivated note events so becca is not updated
|
// import has deactivated note events so becca is not updated, instead we force it to reload
|
||||||
// instead we force it to reload (can be async)
|
beccaLoader.load();
|
||||||
|
|
||||||
|
return note.getPojo();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importAttachmentsToNote(req) {
|
||||||
|
const {parentNoteId} = req.params;
|
||||||
|
const {taskId, last} = req.body;
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
shrinkImages: req.body.shrinkImages !== 'false',
|
||||||
|
};
|
||||||
|
|
||||||
|
const file = req.file;
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
throw new ValidationError("No file has been uploaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentNote = becca.getNoteOrThrow(parentNoteId);
|
||||||
|
|
||||||
|
// running all the event handlers on imported notes (and attributes) is slow
|
||||||
|
// and may produce unintended consequences
|
||||||
|
cls.disableEntityEvents();
|
||||||
|
|
||||||
|
// eliminate flickering during import
|
||||||
|
cls.ignoreEntityChangeIds();
|
||||||
|
|
||||||
|
let note; // typically root of the import - client can show it after finishing the import
|
||||||
|
|
||||||
|
const taskContext = TaskContext.getInstance(taskId, 'import', options);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// FIXME
|
||||||
|
|
||||||
|
note = await singleImportService.importSingleFile(taskContext, file, parentNote);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
const message = `Import failed with following error: '${e.message}'. More details might be in the logs.`;
|
||||||
|
taskContext.reportError(message);
|
||||||
|
|
||||||
|
log.error(message + e.stack);
|
||||||
|
|
||||||
|
return [500, message];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last === "true") {
|
||||||
|
// small timeout to avoid race condition (the message is received before the transaction is committed)
|
||||||
|
setTimeout(() => taskContext.taskSucceeded({
|
||||||
|
parentNoteId: parentNoteId,
|
||||||
|
importedNoteId: note.noteId
|
||||||
|
}), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// import has deactivated note events so becca is not updated, instead we force it to reload
|
||||||
beccaLoader.load();
|
beccaLoader.load();
|
||||||
|
|
||||||
return note.getPojo();
|
return note.getPojo();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
importToBranch
|
importNotesToBranch,
|
||||||
|
importAttachmentsToNote
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const { JSDOM } = require("jsdom");
|
const { JSDOM } = require("jsdom");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
function buildDescendantCountMap(noteIdsToCount) {
|
function buildDescendantCountMap(noteIdsToCount) {
|
||||||
if (!Array.isArray(noteIdsToCount)) {
|
if (!Array.isArray(noteIdsToCount)) {
|
||||||
throw new Error('noteIdsToCount: type error');
|
throw new Error('noteIdsToCount: type error');
|
||||||
@ -345,25 +345,16 @@ function getFilteredBacklinks(note) {
|
|||||||
function getBacklinkCount(req) {
|
function getBacklinkCount(req) {
|
||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
return {
|
||||||
throw new NotFoundError(`Note '${noteId}' not found`);
|
count: getFilteredBacklinks(note).length
|
||||||
}
|
};
|
||||||
else {
|
|
||||||
return {
|
|
||||||
count: getFilteredBacklinks(note).length
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBacklinks(req) {
|
function getBacklinks(req) {
|
||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' was not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let backlinksWithExcerptCount = 0;
|
let backlinksWithExcerptCount = 0;
|
||||||
|
|
||||||
|
@ -8,16 +8,10 @@ const log = require('../../services/log');
|
|||||||
const TaskContext = require('../../services/task_context');
|
const TaskContext = require('../../services/task_context');
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const ValidationError = require("../../errors/validation_error");
|
const ValidationError = require("../../errors/validation_error");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
const blobService = require("../../services/blob");
|
const blobService = require("../../services/blob");
|
||||||
|
|
||||||
function getNote(req) {
|
function getNote(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
return becca.getNoteOrThrow(req.params.noteId);
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' has not been found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return note;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNoteBlob(req) {
|
function getNoteBlob(req) {
|
||||||
@ -27,11 +21,7 @@ function getNoteBlob(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getNoteMetadata(req) {
|
function getNoteMetadata(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' has not been found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentMetadata = note.getContentMetadata();
|
const contentMetadata = note.getContentMetadata();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -132,11 +122,7 @@ function changeTitle(req) {
|
|||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const title = req.body.title;
|
const title = req.body.title;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' has not been found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!note.isContentAvailable()) {
|
if (!note.isContentAvailable()) {
|
||||||
throw new ValidationError(`Note '${noteId}' is not available for change`);
|
throw new ValidationError(`Note '${noteId}' is not available for change`);
|
||||||
@ -232,11 +218,7 @@ function getDeleteNotesPreview(req) {
|
|||||||
|
|
||||||
function forceSaveNoteRevision(req) {
|
function forceSaveNoteRevision(req) {
|
||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!note.isContentAvailable()) {
|
if (!note.isContentAvailable()) {
|
||||||
throw new ValidationError(`Note revision of a protected note cannot be created outside of a protected session.`);
|
throw new ValidationError(`Note revision of a protected note cannot be created outside of a protected session.`);
|
||||||
@ -247,11 +229,7 @@ function forceSaveNoteRevision(req) {
|
|||||||
|
|
||||||
function convertNoteToAttachment(req) {
|
function convertNoteToAttachment(req) {
|
||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attachment: note.convertToParentAttachment({ force: true })
|
attachment: note.convertToParentAttachment({ force: true })
|
||||||
|
@ -7,14 +7,9 @@ const bulkActionService = require("../../services/bulk_actions");
|
|||||||
const cls = require("../../services/cls");
|
const cls = require("../../services/cls");
|
||||||
const {formatAttrForSearch} = require("../../services/attribute_formatter");
|
const {formatAttrForSearch} = require("../../services/attribute_formatter");
|
||||||
const ValidationError = require("../../errors/validation_error");
|
const ValidationError = require("../../errors/validation_error");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
function searchFromNote(req) {
|
function searchFromNote(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' has not been found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note.isDeleted) {
|
if (note.isDeleted) {
|
||||||
// this can be triggered from recent changes, and it's harmless to return empty list rather than fail
|
// this can be triggered from recent changes, and it's harmless to return empty list rather than fail
|
||||||
@ -29,11 +24,7 @@ function searchFromNote(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function searchAndExecute(req) {
|
function searchAndExecute(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' has not been found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note.isDeleted) {
|
if (note.isDeleted) {
|
||||||
// this can be triggered from recent changes, and it's harmless to return empty list rather than fail
|
// this can be triggered from recent changes, and it's harmless to return empty list rather than fail
|
||||||
|
@ -2,16 +2,11 @@
|
|||||||
|
|
||||||
const similarityService = require('../../becca/similarity');
|
const similarityService = require('../../becca/similarity');
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
async function getSimilarNotes(req) {
|
async function getSimilarNotes(req) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
|
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await similarityService.findSimilarNotes(noteId);
|
return await similarityService.findSimilarNotes(noteId);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const sql = require('../../services/sql');
|
const sql = require('../../services/sql');
|
||||||
const becca = require("../../becca/becca");
|
const becca = require("../../becca/becca");
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
function getSchema() {
|
function getSchema() {
|
||||||
const tableNames = sql.getColumn(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
|
const tableNames = sql.getColumn(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
|
||||||
@ -19,11 +18,7 @@ function getSchema() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function execute(req) {
|
function execute(req) {
|
||||||
const note = becca.getNote(req.params.noteId);
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${req.params.noteId}' was not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const queries = note.getContent().split("\n---");
|
const queries = note.getContent().split("\n---");
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const sql = require('../../services/sql');
|
const sql = require('../../services/sql');
|
||||||
const becca = require('../../becca/becca');
|
const becca = require('../../becca/becca');
|
||||||
const NotFoundError = require("../../errors/not_found_error");
|
|
||||||
|
|
||||||
function getNoteSize(req) {
|
function getNoteSize(req) {
|
||||||
const {noteId} = req.params;
|
const {noteId} = req.params;
|
||||||
@ -23,12 +22,7 @@ function getNoteSize(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSubtreeSize(req) {
|
function getSubtreeSize(req) {
|
||||||
const {noteId} = req.params;
|
const note = becca.getNoteOrThrow(req.params.noteId);
|
||||||
const note = becca.notes[noteId];
|
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Note '${noteId}' was not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const subTreeNoteIds = note.getSubtreeNoteIds();
|
const subTreeNoteIds = note.getSubtreeNoteIds();
|
||||||
|
|
||||||
|
@ -180,7 +180,8 @@ function register(app) {
|
|||||||
|
|
||||||
|
|
||||||
route(GET, '/api/branches/:branchId/export/:type/:format/:version/:taskId', [auth.checkApiAuthOrElectron], exportRoute.exportBranch);
|
route(GET, '/api/branches/:branchId/export/:type/:format/:version/:taskId', [auth.checkApiAuthOrElectron], exportRoute.exportBranch);
|
||||||
route(PST, '/api/notes/:parentNoteId/import', [auth.checkApiAuthOrElectron, uploadMiddlewareWithErrorHandling, csrfMiddleware], importRoute.importToBranch, apiResultHandler);
|
route(PST, '/api/notes/:parentNoteId/notes-import', [auth.checkApiAuthOrElectron, uploadMiddlewareWithErrorHandling, csrfMiddleware], importRoute.importNotesToBranch, apiResultHandler);
|
||||||
|
route(PST, '/api/notes/:parentNoteId/attachments-import', [auth.checkApiAuthOrElectron, uploadMiddlewareWithErrorHandling, csrfMiddleware], importRoute.importAttachmentsToNote, apiResultHandler);
|
||||||
|
|
||||||
apiRoute(GET, '/api/notes/:noteId/attributes', attributesRoute.getEffectiveNoteAttributes);
|
apiRoute(GET, '/api/notes/:noteId/attributes', attributesRoute.getEffectiveNoteAttributes);
|
||||||
apiRoute(PST, '/api/notes/:noteId/attributes', attributesRoute.addNoteAttribute);
|
apiRoute(PST, '/api/notes/:noteId/attributes', attributesRoute.addNoteAttribute);
|
||||||
|
@ -12,8 +12,6 @@ const sanitizeFilename = require('sanitize-filename');
|
|||||||
const isSvg = require('is-svg');
|
const isSvg = require('is-svg');
|
||||||
const isAnimated = require('is-animated');
|
const isAnimated = require('is-animated');
|
||||||
const htmlSanitizer = require("./html_sanitizer");
|
const htmlSanitizer = require("./html_sanitizer");
|
||||||
const {attach} = require("jsdom/lib/jsdom/living/helpers/svg/basic-types.js");
|
|
||||||
const NotFoundError = require("../errors/not_found_error.js");
|
|
||||||
|
|
||||||
async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
|
async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
|
||||||
const compressImages = optionService.getOptionBool("compressImages");
|
const compressImages = optionService.getOptionBool("compressImages");
|
||||||
@ -142,11 +140,7 @@ function saveImageToAttachment(noteId, uploadBuffer, originalName, shrinkImageSw
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileName = sanitizeFilename(originalName);
|
const fileName = sanitizeFilename(originalName);
|
||||||
const note = becca.getNote(noteId);
|
const note = becca.getNoteOrThrow(noteId);
|
||||||
|
|
||||||
if (!note) {
|
|
||||||
throw new NotFoundError(`Could not find note '${noteId}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const attachment = note.saveAttachment({
|
const attachment = note.saveAttachment({
|
||||||
role: 'image',
|
role: 'image',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user