mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Chore: Convert ResourceService to TypeScript
This commit is contained in:
parent
88a2f9c85c
commit
5269a4b7fa
@ -184,6 +184,9 @@ packages/app-cli/tests/services_InteropService.js.map
|
||||
packages/app-cli/tests/services_PluginService.d.ts
|
||||
packages/app-cli/tests/services_PluginService.js
|
||||
packages/app-cli/tests/services_PluginService.js.map
|
||||
packages/app-cli/tests/services_ResourceService.d.ts
|
||||
packages/app-cli/tests/services_ResourceService.js
|
||||
packages/app-cli/tests/services_ResourceService.js.map
|
||||
packages/app-cli/tests/services_keychainService.d.ts
|
||||
packages/app-cli/tests/services_keychainService.js
|
||||
packages/app-cli/tests/services_keychainService.js.map
|
||||
@ -898,6 +901,9 @@ packages/lib/services/ResourceEditWatcher/index.js.map
|
||||
packages/lib/services/ResourceEditWatcher/reducer.d.ts
|
||||
packages/lib/services/ResourceEditWatcher/reducer.js
|
||||
packages/lib/services/ResourceEditWatcher/reducer.js.map
|
||||
packages/lib/services/ResourceService.d.ts
|
||||
packages/lib/services/ResourceService.js
|
||||
packages/lib/services/ResourceService.js.map
|
||||
packages/lib/services/SettingUtils.d.ts
|
||||
packages/lib/services/SettingUtils.js
|
||||
packages/lib/services/SettingUtils.js.map
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -176,6 +176,9 @@ packages/app-cli/tests/services_InteropService.js.map
|
||||
packages/app-cli/tests/services_PluginService.d.ts
|
||||
packages/app-cli/tests/services_PluginService.js
|
||||
packages/app-cli/tests/services_PluginService.js.map
|
||||
packages/app-cli/tests/services_ResourceService.d.ts
|
||||
packages/app-cli/tests/services_ResourceService.js
|
||||
packages/app-cli/tests/services_ResourceService.js.map
|
||||
packages/app-cli/tests/services_keychainService.d.ts
|
||||
packages/app-cli/tests/services_keychainService.js
|
||||
packages/app-cli/tests/services_keychainService.js.map
|
||||
@ -890,6 +893,9 @@ packages/lib/services/ResourceEditWatcher/index.js.map
|
||||
packages/lib/services/ResourceEditWatcher/reducer.d.ts
|
||||
packages/lib/services/ResourceEditWatcher/reducer.js
|
||||
packages/lib/services/ResourceEditWatcher/reducer.js.map
|
||||
packages/lib/services/ResourceService.d.ts
|
||||
packages/lib/services/ResourceService.js
|
||||
packages/lib/services/ResourceService.js.map
|
||||
packages/lib/services/SettingUtils.d.ts
|
||||
packages/lib/services/SettingUtils.js
|
||||
packages/lib/services/SettingUtils.js.map
|
||||
|
6
.ignore
6
.ignore
@ -131,6 +131,9 @@ packages/app-cli/tests/services_InteropService.js.map
|
||||
packages/app-cli/tests/services_PluginService.d.ts
|
||||
packages/app-cli/tests/services_PluginService.js
|
||||
packages/app-cli/tests/services_PluginService.js.map
|
||||
packages/app-cli/tests/services_ResourceService.d.ts
|
||||
packages/app-cli/tests/services_ResourceService.js
|
||||
packages/app-cli/tests/services_ResourceService.js.map
|
||||
packages/app-cli/tests/services_keychainService.d.ts
|
||||
packages/app-cli/tests/services_keychainService.js
|
||||
packages/app-cli/tests/services_keychainService.js.map
|
||||
@ -845,6 +848,9 @@ packages/lib/services/ResourceEditWatcher/index.js.map
|
||||
packages/lib/services/ResourceEditWatcher/reducer.d.ts
|
||||
packages/lib/services/ResourceEditWatcher/reducer.js
|
||||
packages/lib/services/ResourceEditWatcher/reducer.js.map
|
||||
packages/lib/services/ResourceService.d.ts
|
||||
packages/lib/services/ResourceService.js
|
||||
packages/lib/services/ResourceService.js.map
|
||||
packages/lib/services/SettingUtils.d.ts
|
||||
packages/lib/services/SettingUtils.js
|
||||
packages/lib/services/SettingUtils.js.map
|
||||
|
@ -1,6 +1,6 @@
|
||||
const BaseApplication = require('@joplin/lib/BaseApplication').default;
|
||||
const { FoldersScreenUtils } = require('@joplin/lib/folders-screen-utils.js');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem.js');
|
||||
|
@ -4,7 +4,7 @@
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { asyncTest, fileContentEqual, revisionService, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const ItemChangeUtils = require('@joplin/lib/services/ItemChangeUtils');
|
||||
const Note = require('@joplin/lib/models/Note');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
|
@ -1,38 +1,14 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import time from '@joplin/lib/time';
|
||||
import NoteResource from '@joplin/lib/models/NoteResource';
|
||||
import ResourceService from '@joplin/lib/services/ResourceService';
|
||||
import shim from '@joplin/lib/shim';
|
||||
|
||||
|
||||
const time = require('@joplin/lib/time').default;
|
||||
const { asyncTest, resourceService, decryptionWorker, encryptionService, loadEncryptionMasterKey, allSyncTargetItemsEncrypted, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
|
||||
const InteropService = require('@joplin/lib/services/interop/InteropService').default;
|
||||
const { asyncTest, resourceService, decryptionWorker, encryptionService, loadEncryptionMasterKey, allSyncTargetItemsEncrypted, setupDatabaseAndSynchronizer, db, synchronizer, switchClient } = require('./test-utils.js');
|
||||
const Folder = require('@joplin/lib/models/Folder.js');
|
||||
const Note = require('@joplin/lib/models/Note.js');
|
||||
const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const NoteTag = require('@joplin/lib/models/NoteTag.js');
|
||||
const Resource = require('@joplin/lib/models/Resource.js');
|
||||
const ItemChange = require('@joplin/lib/models/ItemChange.js');
|
||||
const NoteResource = require('@joplin/lib/models/NoteResource').default;
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService.js');
|
||||
const fs = require('fs-extra');
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils');
|
||||
const ObjectUtils = require('@joplin/lib/ObjectUtils');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
function exportDir() {
|
||||
return `${__dirname}/export`;
|
||||
}
|
||||
|
||||
function fieldsEqual(model1, model2, fieldNames) {
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
const f = fieldNames[i];
|
||||
expect(model1[f]).toBe(model2[f], `For key ${f}`);
|
||||
}
|
||||
}
|
||||
|
||||
describe('services_ResourceService', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
@ -99,7 +75,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
it('should not delete a resource that has never been associated with any note, because it probably means the resource came via sync, and associated note has not arrived yet', asyncTest(async () => {
|
||||
const service = new ResourceService();
|
||||
const resource = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
|
||||
await service.indexNoteResources();
|
||||
await service.deleteOrphanResources(0);
|
||||
@ -130,9 +106,8 @@ describe('services_ResourceService', function() {
|
||||
const service = new ResourceService();
|
||||
|
||||
const folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
const resource1 = (await Resource.all())[0];
|
||||
const note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
@ -212,4 +187,30 @@ describe('services_ResourceService', function() {
|
||||
expect(!!nr.is_associated).toBe(true); // And it should have fixed the situation by re-indexing the note content
|
||||
}));
|
||||
|
||||
// it('should auto-delete resource even if the associated note was deleted immediately', asyncTest(async () => {
|
||||
// // Previoulsy, when a resource was be attached to a note, then the
|
||||
// // note was immediately deleted, the ResourceService would not have
|
||||
// // time to quick in an index the resource/note relation. It means
|
||||
// // that when doing the orphan resource deletion job, those
|
||||
// // resources would permanently stay behing.
|
||||
// // https://github.com/laurent22/joplin/issues/932
|
||||
|
||||
// const service = new ResourceService();
|
||||
|
||||
// let note = await Note.save({});
|
||||
// note = await shim.attachFileToNote(note, `${__dirname}/../tests/support/photo.jpg`);
|
||||
// const resource = (await Resource.all())[0];
|
||||
|
||||
// const noteIds = await NoteResource.associatedNoteIds(resource.id);
|
||||
|
||||
// expect(noteIds[0]).toBe(note.id);
|
||||
|
||||
// await Note.save({ id: note.id, body: '' });
|
||||
|
||||
// await resourceService().indexNoteResources();
|
||||
// await service.deleteOrphanResources(0);
|
||||
|
||||
// expect((await Resource.all()).length).toBe(0);
|
||||
// }));
|
||||
|
||||
});
|
@ -12,7 +12,7 @@ const ItemChange = require('@joplin/lib/models/ItemChange');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Resource = require('@joplin/lib/models/Resource.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService.js');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
|
@ -12,7 +12,7 @@
|
||||
// const Setting = require('@joplin/lib/models/Setting');
|
||||
// const Resource = require('@joplin/lib/models/Resource.js');
|
||||
// const shim = require('@joplin/lib/shim').default;
|
||||
// const ResourceService = require('@joplin/lib/services/ResourceService.js');
|
||||
// const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
|
||||
// process.on('unhandledRejection', (reason, p) => {
|
||||
// console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
|
@ -8,7 +8,7 @@ const Resource = require('@joplin/lib/models/Resource');
|
||||
const Note = require('@joplin/lib/models/Note');
|
||||
const Tag = require('@joplin/lib/models/Tag');
|
||||
const NoteTag = require('@joplin/lib/models/NoteTag');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
|
||||
async function msleep(ms:number) {
|
||||
return new Promise((resolve) => {
|
||||
|
@ -38,7 +38,7 @@ const SyncTargetDropbox = require('@joplin/lib/SyncTargetDropbox.js');
|
||||
const SyncTargetAmazonS3 = require('@joplin/lib/SyncTargetAmazonS3.js');
|
||||
const EncryptionService = require('@joplin/lib/services/EncryptionService.js');
|
||||
const DecryptionWorker = require('@joplin/lib/services/DecryptionWorker.js');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService.js');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const RevisionService = require('@joplin/lib/services/RevisionService.js');
|
||||
const ResourceFetcher = require('@joplin/lib/services/ResourceFetcher.js');
|
||||
const KvStore = require('@joplin/lib/services/KvStore').default;
|
||||
|
@ -27,7 +27,7 @@ const Tag = require('@joplin/lib/models/Tag.js');
|
||||
const { reg } = require('@joplin/lib/registry.js');
|
||||
const packageInfo = require('./packageInfo.js');
|
||||
const DecryptionWorker = require('@joplin/lib/services/DecryptionWorker');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const ClipperServer = require('@joplin/lib/ClipperServer');
|
||||
const ExternalEditWatcher = require('@joplin/lib/services/ExternalEditWatcher');
|
||||
const { webFrame } = require('electron');
|
||||
|
@ -31,7 +31,7 @@ const MasterKey = require('@joplin/lib/models/MasterKey.js');
|
||||
const Revision = require('@joplin/lib/models/Revision.js');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const BaseService = require('@joplin/lib/services/BaseService').default;
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService');
|
||||
const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
||||
const RevisionService = require('@joplin/lib/services/RevisionService');
|
||||
const KvStore = require('@joplin/lib/services/KvStore').default;
|
||||
const { JoplinDatabase } = require('@joplin/lib/joplin-database.js');
|
||||
|
@ -1,7 +1,7 @@
|
||||
const BaseModel = require('../BaseModel').default;
|
||||
const BaseItem = require('./BaseItem.js');
|
||||
const ItemChange = require('./ItemChange.js');
|
||||
const NoteResource = require('./NoteResource.js');
|
||||
const NoteResource = require('./NoteResource').default;
|
||||
const ResourceLocalState = require('./ResourceLocalState.js');
|
||||
const Setting = require('./Setting').default;
|
||||
const pathUtils = require('../path-utils');
|
||||
|
@ -2,7 +2,7 @@ const BaseItem = require('../models/BaseItem');
|
||||
const BaseModel = require('../BaseModel').default;
|
||||
const MasterKey = require('../models/MasterKey');
|
||||
const Resource = require('../models/Resource');
|
||||
const ResourceService = require('./ResourceService');
|
||||
const ResourceService = require('./ResourceService').default;
|
||||
const Logger = require('../Logger').default;
|
||||
const EventEmitter = require('events');
|
||||
const shim = require('../shim').default;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const Resource = require('../models/Resource');
|
||||
const Setting = require('../models/Setting').default;
|
||||
const BaseService = require('./BaseService').default;
|
||||
const ResourceService = require('./ResourceService');
|
||||
const ResourceService = require('./ResourceService').default;
|
||||
const { Dirnames } = require('./synchronizer/utils/types');
|
||||
const Logger = require('../Logger').default;
|
||||
const EventEmitter = require('events');
|
||||
|
@ -1,31 +1,24 @@
|
||||
import NoteResource from '../models/NoteResource';
|
||||
import BaseModel from '../BaseModel';
|
||||
import BaseService from './BaseService';
|
||||
import Setting from '../models/Setting';
|
||||
import shim from '../shim';
|
||||
const ItemChange = require('../models/ItemChange');
|
||||
const NoteResource = require('../models/NoteResource').default;
|
||||
const Note = require('../models/Note');
|
||||
const Resource = require('../models/Resource');
|
||||
const BaseModel = require('../BaseModel').default;
|
||||
const BaseService = require('./BaseService').default;
|
||||
const SearchEngine = require('./searchengine/SearchEngine');
|
||||
const Setting = require('../models/Setting').default;
|
||||
const shim = require('../shim').default;
|
||||
const ItemChangeUtils = require('./ItemChangeUtils');
|
||||
const { sprintf } = require('sprintf-js');
|
||||
|
||||
class ResourceService extends BaseService {
|
||||
constructor() {
|
||||
super();
|
||||
export default class ResourceService extends BaseService {
|
||||
|
||||
this.maintenanceCalls_ = [];
|
||||
this.maintenanceTimer1_ = null;
|
||||
this.maintenanceTimer2_ = null;
|
||||
}
|
||||
private static isRunningInBackground_:boolean = false;
|
||||
|
||||
static instance() {
|
||||
if (this.instance_) return this.instance_;
|
||||
this.instance_ = new ResourceService();
|
||||
return this.instance_;
|
||||
}
|
||||
private maintenanceCalls_:boolean[] = [];
|
||||
private maintenanceTimer1_:any = null
|
||||
private maintenanceTimer2_:any = null
|
||||
|
||||
async indexNoteResources() {
|
||||
public async indexNoteResources() {
|
||||
this.logger().info('ResourceService::indexNoteResources: Start');
|
||||
|
||||
await ItemChange.waitForAllSaved();
|
||||
@ -46,10 +39,10 @@ class ResourceService extends BaseService {
|
||||
|
||||
if (!changes.length) break;
|
||||
|
||||
const noteIds = changes.map(a => a.item_id);
|
||||
const noteIds = changes.map((a:any) => a.item_id);
|
||||
const notes = await Note.modelSelectAll(`SELECT id, title, body, encryption_applied FROM notes WHERE id IN ("${noteIds.join('","')}")`);
|
||||
|
||||
const noteById = noteId => {
|
||||
const noteById = (noteId:string) => {
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
if (notes[i].id === noteId) return notes[i];
|
||||
}
|
||||
@ -77,7 +70,7 @@ class ResourceService extends BaseService {
|
||||
break;
|
||||
}
|
||||
|
||||
await this.setAssociatedResources_(note);
|
||||
await this.setAssociatedResources(note.id, note.body);
|
||||
} else {
|
||||
this.logger().warn(`ResourceService::indexNoteResources: A change was recorded for a note that has been deleted: ${change.item_id}`);
|
||||
}
|
||||
@ -102,12 +95,12 @@ class ResourceService extends BaseService {
|
||||
this.logger().info('ResourceService::indexNoteResources: Completed');
|
||||
}
|
||||
|
||||
async setAssociatedResources_(note) {
|
||||
const resourceIds = await Note.linkedResourceIds(note.body);
|
||||
await NoteResource.setAssociatedResources(note.id, resourceIds);
|
||||
public async setAssociatedResources(noteId:string, noteBody:string) {
|
||||
const resourceIds = await Note.linkedResourceIds(noteBody);
|
||||
await NoteResource.setAssociatedResources(noteId, resourceIds);
|
||||
}
|
||||
|
||||
async deleteOrphanResources(expiryDelay = null) {
|
||||
public async deleteOrphanResources(expiryDelay:number = null) {
|
||||
if (expiryDelay === null) expiryDelay = Setting.value('revisionService.ttlDays') * 24 * 60 * 60 * 1000;
|
||||
const resourceIds = await NoteResource.orphanResources(expiryDelay);
|
||||
this.logger().info('ResourceService::deleteOrphanResources:', resourceIds);
|
||||
@ -118,7 +111,7 @@ class ResourceService extends BaseService {
|
||||
const note = await Note.load(results[0].id);
|
||||
if (note) {
|
||||
this.logger().info(sprintf('ResourceService::deleteOrphanResources: Skipping deletion of resource %s because it is still referenced in note %s. Re-indexing note content to fix the issue.', resourceId, note.id));
|
||||
await this.setAssociatedResources_(note);
|
||||
await this.setAssociatedResources(note.id, note.body);
|
||||
}
|
||||
} else {
|
||||
await Resource.delete(resourceId);
|
||||
@ -126,7 +119,7 @@ class ResourceService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
static async autoSetFileSize(resourceId, filePath, waitTillExists = true) {
|
||||
private static async autoSetFileSize(resourceId:string, filePath:string, waitTillExists:boolean = true) {
|
||||
const itDoes = await shim.fsDriver().waitTillExists(filePath, waitTillExists ? 10000 : 0);
|
||||
if (!itDoes) {
|
||||
// this.logger().warn('Trying to set file size on non-existent resource:', resourceId, filePath);
|
||||
@ -136,7 +129,7 @@ class ResourceService extends BaseService {
|
||||
await Resource.setFileSizeOnly(resourceId, fileStat.size);
|
||||
}
|
||||
|
||||
static async autoSetFileSizes() {
|
||||
public static async autoSetFileSizes() {
|
||||
const resources = await Resource.needFileSizeSet();
|
||||
|
||||
for (const r of resources) {
|
||||
@ -144,7 +137,7 @@ class ResourceService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
async maintenance() {
|
||||
public async maintenance() {
|
||||
this.maintenanceCalls_.push(true);
|
||||
try {
|
||||
await this.indexNoteResources();
|
||||
@ -154,7 +147,7 @@ class ResourceService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
static runInBackground() {
|
||||
public static runInBackground() {
|
||||
if (this.isRunningInBackground_) return;
|
||||
|
||||
this.isRunningInBackground_ = true;
|
||||
@ -169,13 +162,13 @@ class ResourceService extends BaseService {
|
||||
}, 1000 * 60 * 60 * 4);
|
||||
}
|
||||
|
||||
async cancelTimers() {
|
||||
public async cancelTimers() {
|
||||
if (this.maintenanceTimer1_) {
|
||||
shim.clearTimeout(this.maintenanceTimer1);
|
||||
shim.clearTimeout(this.maintenanceTimer1_);
|
||||
this.maintenanceTimer1_ = null;
|
||||
}
|
||||
if (this.maintenanceTimer2_) {
|
||||
shim.clearInterval(this.maintenanceTimer2);
|
||||
shim.clearInterval(this.maintenanceTimer2_);
|
||||
this.maintenanceTimer2_ = null;
|
||||
}
|
||||
|
||||
@ -188,6 +181,13 @@ class ResourceService extends BaseService {
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ResourceService;
|
||||
private static instance_:ResourceService = null;
|
||||
|
||||
public static instance() {
|
||||
if (this.instance_) return this.instance_;
|
||||
this.instance_ = new ResourceService();
|
||||
return this.instance_;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user