mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 03:46:37 +01:00 
			
		
		
		
	scheduled attachment deletion WIP
This commit is contained in:
		@@ -1132,6 +1132,17 @@ class BNote extends AbstractBeccaEntity {
 | 
			
		||||
            .map(row => new BAttachment(row))[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @returns {BAttachment[]} */
 | 
			
		||||
    getAttachmentByRole(role) {
 | 
			
		||||
        return sql.getRows(`
 | 
			
		||||
                SELECT attachments.*
 | 
			
		||||
                FROM attachments 
 | 
			
		||||
                WHERE parentId = ? 
 | 
			
		||||
                  AND role = ?
 | 
			
		||||
                  AND isDeleted = 0`, [this.noteId, role])
 | 
			
		||||
            .map(row => new BAttachment(row));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gives all possible note paths leading to this note. Paths containing search note are ignored (could form cycles)
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ function parseDate(str) {
 | 
			
		||||
        return new Date(Date.parse(str));
 | 
			
		||||
    }
 | 
			
		||||
    catch (e) {
 | 
			
		||||
        throw new Error(`Can't parse date from ${str}: ${e.stack}`);
 | 
			
		||||
        throw new Error(`Can't parse date from '${str}': ${e.message} ${e.stack}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -100,6 +100,17 @@ export default class AttachmentDetailWidget extends BasicWidget {
 | 
			
		||||
                .text(this.attachment.title);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const {utcDateScheduledForDeletionSince} = this.attachment;
 | 
			
		||||
 | 
			
		||||
        if (utcDateScheduledForDeletionSince) {
 | 
			
		||||
            const scheduledSinceTimestamp = utils.parseDate(utcDateScheduledForDeletionSince)?.getTime();
 | 
			
		||||
            const interval = 3600 * 1000;
 | 
			
		||||
            const deletionTimestamp = scheduledSinceTimestamp + interval;
 | 
			
		||||
            const willBeDeletedInSeconds = Math.round((deletionTimestamp - Date.now()) / 1000);
 | 
			
		||||
 | 
			
		||||
            this.$wrapper.find('.attachment-title').append(`Will be deleted in ${willBeDeletedInSeconds} seconds.`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.$wrapper.find('.attachment-details')
 | 
			
		||||
            .text(`Role: ${this.attachment.role}, Size: ${utils.formatSize(this.attachment.contentLength)}`);
 | 
			
		||||
        this.$wrapper.find('.attachment-actions-container').append(this.attachmentActionsWidget.render());
 | 
			
		||||
 
 | 
			
		||||
@@ -336,6 +336,29 @@ function protectNote(note, protect) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkImageAttachments(note, content) {
 | 
			
		||||
    const re = /src="[^"]*api\/attachments\/([a-zA-Z0-9_]+)\/image/g;
 | 
			
		||||
    const foundAttachmentIds = new Set();
 | 
			
		||||
    let match;
 | 
			
		||||
 | 
			
		||||
    while (match = re.exec(content)) {
 | 
			
		||||
        foundAttachmentIds.push(match[1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const attachment of note.getAttachmentByRole('image')) {
 | 
			
		||||
        const imageInContent = foundAttachmentIds.has(attachment.attachmentId);
 | 
			
		||||
 | 
			
		||||
        if (attachment.utcDateScheduledForDeletionSince && imageInContent) {
 | 
			
		||||
            attachment.utcDateScheduledForDeletionSince = null;
 | 
			
		||||
            attachment.save();
 | 
			
		||||
        } else if (!attachment.utcDateScheduledForDeletionSince && !imageInContent) {
 | 
			
		||||
            attachment.utcDateScheduledForDeletionSince = dateUtils.utcNowDateTime();
 | 
			
		||||
            attachment.save();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function findImageLinks(content, foundLinks) {
 | 
			
		||||
    const re = /src="[^"]*api\/images\/([a-zA-Z0-9_]+)\//g;
 | 
			
		||||
    let match;
 | 
			
		||||
@@ -556,6 +579,8 @@ function saveLinks(note, content) {
 | 
			
		||||
        content = findImageLinks(content, foundLinks);
 | 
			
		||||
        content = findInternalLinks(content, foundLinks);
 | 
			
		||||
        content = findIncludeNoteLinks(content, foundLinks);
 | 
			
		||||
 | 
			
		||||
        checkImageAttachments(note, content);
 | 
			
		||||
    }
 | 
			
		||||
    else if (note.type === 'relationMap') {
 | 
			
		||||
        findRelationMapLinks(content, foundLinks);
 | 
			
		||||
@@ -735,11 +760,13 @@ function scanForLinks(note, content) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        const newContent = saveLinks(note, content);
 | 
			
		||||
        sql.transactional(() => {
 | 
			
		||||
            const newContent = saveLinks(note, content);
 | 
			
		||||
 | 
			
		||||
        if (content !== newContent) {
 | 
			
		||||
            note.setContent(newContent);
 | 
			
		||||
        }
 | 
			
		||||
            if (content !== newContent) {
 | 
			
		||||
                note.setContent(newContent);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    catch (e) {
 | 
			
		||||
        log.error(`Could not scan for links note ${note.noteId}: ${e.message} ${e.stack}`);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user