mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
All: Make sure resource filesize is set in all cases
This commit is contained in:
parent
ed3970be81
commit
e1b7b64e1b
5
CliClient/package-lock.json
generated
5
CliClient/package-lock.json
generated
@ -744,6 +744,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
|
||||||
"integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU="
|
"integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU="
|
||||||
},
|
},
|
||||||
|
"file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||||
|
},
|
||||||
"find-up": {
|
"find-up": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
"diacritics": "^1.3.0",
|
"diacritics": "^1.3.0",
|
||||||
"diff-match-patch": "^1.0.4",
|
"diff-match-patch": "^1.0.4",
|
||||||
"es6-promise-pool": "^2.5.0",
|
"es6-promise-pool": "^2.5.0",
|
||||||
|
"file-uri-to-path": "^1.0.0",
|
||||||
"follow-redirects": "^1.2.4",
|
"follow-redirects": "^1.2.4",
|
||||||
"form-data": "^2.1.4",
|
"form-data": "^2.1.4",
|
||||||
"fs-extra": "^5.0.0",
|
"fs-extra": "^5.0.0",
|
||||||
|
@ -899,6 +899,29 @@ describe('Synchronizer', function() {
|
|||||||
expect(ls.fetch_error).toBe('did not work');
|
expect(ls.fetch_error).toBe('did not work');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should set the resource file size if it is missing', asyncTest(async () => {
|
||||||
|
while (insideBeforeEach) await time.msleep(500);
|
||||||
|
|
||||||
|
let folder1 = await Folder.save({ title: "folder1" });
|
||||||
|
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||||
|
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||||
|
await synchronizer().start();
|
||||||
|
|
||||||
|
await switchClient(2);
|
||||||
|
|
||||||
|
await synchronizer().start();
|
||||||
|
let r1 = (await Resource.all())[0];
|
||||||
|
await Resource.setFileSizeOnly(r1.id, -1);
|
||||||
|
r1 = await Resource.load(r1.id);
|
||||||
|
expect(r1.size).toBe(-1);
|
||||||
|
|
||||||
|
const fetcher = new ResourceFetcher(() => { return synchronizer().api() });
|
||||||
|
fetcher.queueDownload(r1.id);
|
||||||
|
await fetcher.waitForAllFinished();
|
||||||
|
r1 = await Resource.load(r1.id);
|
||||||
|
expect(r1.size).toBe(2720);
|
||||||
|
}));
|
||||||
|
|
||||||
it('should delete resources', asyncTest(async () => {
|
it('should delete resources', asyncTest(async () => {
|
||||||
while (insideBeforeEach) await time.msleep(500);
|
while (insideBeforeEach) await time.msleep(500);
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ async function switchClient(id) {
|
|||||||
Note.db_ = databases_[id];
|
Note.db_ = databases_[id];
|
||||||
BaseItem.db_ = databases_[id];
|
BaseItem.db_ = databases_[id];
|
||||||
Setting.db_ = databases_[id];
|
Setting.db_ = databases_[id];
|
||||||
|
Resource.db_ = databases_[id];
|
||||||
|
|
||||||
BaseItem.encryptionService_ = encryptionServices_[id];
|
BaseItem.encryptionService_ = encryptionServices_[id];
|
||||||
Resource.encryptionService_ = encryptionServices_[id];
|
Resource.encryptionService_ = encryptionServices_[id];
|
||||||
|
@ -30,6 +30,7 @@ const Menu = bridge().Menu;
|
|||||||
const MenuItem = bridge().MenuItem;
|
const MenuItem = bridge().MenuItem;
|
||||||
const PluginManager = require('lib/services/PluginManager');
|
const PluginManager = require('lib/services/PluginManager');
|
||||||
const RevisionService = require('lib/services/RevisionService');
|
const RevisionService = require('lib/services/RevisionService');
|
||||||
|
const MigrationService = require('lib/services/MigrationService');
|
||||||
|
|
||||||
const pluginClasses = [
|
const pluginClasses = [
|
||||||
require('./plugins/GotoAnything.min'),
|
require('./plugins/GotoAnything.min'),
|
||||||
@ -1037,6 +1038,7 @@ class Application extends BaseApplication {
|
|||||||
|
|
||||||
// Make it available to the console window - useful to call revisionService.collectRevisions()
|
// Make it available to the console window - useful to call revisionService.collectRevisions()
|
||||||
window.revisionService = RevisionService.instance();
|
window.revisionService = RevisionService.instance();
|
||||||
|
window.migrationService = MigrationService.instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,8 @@ android {
|
|||||||
applicationId "net.cozic.joplin"
|
applicationId "net.cozic.joplin"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 2097482
|
versionCode 2097483
|
||||||
versionName "1.0.246"
|
versionName "1.0.247"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "x86"
|
abiFilters "armeabi-v7a", "x86"
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ const Resource = require('lib/models/Resource');
|
|||||||
const Setting = require('lib/models/Setting');
|
const Setting = require('lib/models/Setting');
|
||||||
const { shim } = require('lib/shim');
|
const { shim } = require('lib/shim');
|
||||||
const { reg } = require('lib/registry.js');
|
const { reg } = require('lib/registry.js');
|
||||||
|
const { fileExtension } = require('lib/path-utils.js');
|
||||||
|
|
||||||
const script = {};
|
const script = {};
|
||||||
|
|
||||||
@ -10,7 +11,10 @@ script.exec = async function() {
|
|||||||
|
|
||||||
const queries = [];
|
const queries = [];
|
||||||
for (const stat of stats) {
|
for (const stat of stats) {
|
||||||
|
if (fileExtension(stat.path) === 'crypted') continue;
|
||||||
const resourceId = Resource.pathToId(stat.path);
|
const resourceId = Resource.pathToId(stat.path);
|
||||||
|
if (!resourceId) continue;
|
||||||
|
|
||||||
queries.push({ sql: 'UPDATE resources SET `size` = ? WHERE id = ?', params: [stat.size, resourceId] });
|
queries.push({ sql: 'UPDATE resources SET `size` = ? WHERE id = ?', params: [stat.size, resourceId] });
|
||||||
|
|
||||||
if (queries.length >= 1000) {
|
if (queries.length >= 1000) {
|
||||||
|
@ -214,6 +214,13 @@ class Resource extends BaseItem {
|
|||||||
await ResourceLocalState.save(Object.assign({}, state, { resource_id: id }));
|
await ResourceLocalState.save(Object.assign({}, state, { resource_id: id }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only set the `size` field and nothing else, not even the update_time
|
||||||
|
// This is because it's only necessary to do it once after migration 20
|
||||||
|
// and each client does it so there's no need to sync the resource.
|
||||||
|
static async setFileSizeOnly(resourceId, fileSize) {
|
||||||
|
return this.db().exec('UPDATE resources set `size` = ? WHERE id = ?', [fileSize, resourceId]);
|
||||||
|
}
|
||||||
|
|
||||||
static async batchDelete(ids, options = null) {
|
static async batchDelete(ids, options = null) {
|
||||||
// For resources, there's not really batch deleting since there's the file data to delete
|
// For resources, there's not really batch deleting since there's the file data to delete
|
||||||
// too, so each is processed one by one with the item being deleted last (since the db
|
// too, so each is processed one by one with the item being deleted last (since the db
|
||||||
|
@ -14,16 +14,19 @@ class MigrationService extends BaseService {
|
|||||||
return this.instance_;
|
return this.instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async runScript(num) {
|
||||||
|
const script = Migration.script(num);
|
||||||
|
await script.exec();
|
||||||
|
}
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
const migrations = await Migration.migrationsToDo();
|
const migrations = await Migration.migrationsToDo();
|
||||||
|
|
||||||
for (const migration of migrations) {
|
for (const migration of migrations) {
|
||||||
this.logger().info('Running migration: ' + migration.number);
|
this.logger().info('Running migration: ' + migration.number);
|
||||||
|
|
||||||
const script = Migration.script(migration.number);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await script.exec();
|
await this.runScript(migration.number);
|
||||||
await Migration.delete(migration.id);
|
await Migration.delete(migration.id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger().error('Cannot run migration: ' + migration.number, error);
|
this.logger().error('Cannot run migration: ' + migration.number, error);
|
||||||
|
@ -3,6 +3,7 @@ const BaseService = require('lib/services/BaseService');
|
|||||||
const BaseSyncTarget = require('lib/BaseSyncTarget');
|
const BaseSyncTarget = require('lib/BaseSyncTarget');
|
||||||
const { Logger } = require('lib/logger.js');
|
const { Logger } = require('lib/logger.js');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
|
const { shim } = require('lib/shim');
|
||||||
|
|
||||||
class ResourceFetcher extends BaseService {
|
class ResourceFetcher extends BaseService {
|
||||||
|
|
||||||
@ -97,7 +98,17 @@ class ResourceFetcher extends BaseService {
|
|||||||
if (this.fetchingItems_[resourceId]) return;
|
if (this.fetchingItems_[resourceId]) return;
|
||||||
this.fetchingItems_[resourceId] = true;
|
this.fetchingItems_[resourceId] = true;
|
||||||
|
|
||||||
const completeDownload = (emitDownloadComplete = true) => {
|
const completeDownload = async (emitDownloadComplete = true, localResourceContentPath = '') => {
|
||||||
|
|
||||||
|
// 2019-05-12: This is only necessary to set the file size of the resources that come via
|
||||||
|
// sync. The other ones have been done using migrations/20.js. This code can be removed
|
||||||
|
// after a few months.
|
||||||
|
if (resource.size < 0 && localResourceContentPath) {
|
||||||
|
const itDoes = await shim.fsDriver().waitTillExists(localResourceContentPath);
|
||||||
|
const fileStat = await shim.fsDriver().stat(localResourceContentPath);
|
||||||
|
await Resource.setFileSizeOnly(resource.id, fileStat.size);
|
||||||
|
}
|
||||||
|
|
||||||
delete this.fetchingItems_[resource.id];
|
delete this.fetchingItems_[resource.id];
|
||||||
this.scheduleQueueProcess();
|
this.scheduleQueueProcess();
|
||||||
if (emitDownloadComplete) this.eventEmitter_.emit('downloadComplete', { id: resource.id });
|
if (emitDownloadComplete) this.eventEmitter_.emit('downloadComplete', { id: resource.id });
|
||||||
@ -110,7 +121,7 @@ class ResourceFetcher extends BaseService {
|
|||||||
// Shouldn't happen, but just to be safe don't re-download the
|
// Shouldn't happen, but just to be safe don't re-download the
|
||||||
// resource if it's already been downloaded.
|
// resource if it's already been downloaded.
|
||||||
if (localState.fetch_status === Resource.FETCH_STATUS_DONE) {
|
if (localState.fetch_status === Resource.FETCH_STATUS_DONE) {
|
||||||
completeDownload(false);
|
await completeDownload(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,11 +139,11 @@ class ResourceFetcher extends BaseService {
|
|||||||
fileApi.get(remoteResourceContentPath, { path: localResourceContentPath, target: "file" }).then(async () => {
|
fileApi.get(remoteResourceContentPath, { path: localResourceContentPath, target: "file" }).then(async () => {
|
||||||
await Resource.setLocalState(resource, { fetch_status: Resource.FETCH_STATUS_DONE });
|
await Resource.setLocalState(resource, { fetch_status: Resource.FETCH_STATUS_DONE });
|
||||||
this.logger().debug('ResourceFetcher: Resource downloaded: ' + resource.id);
|
this.logger().debug('ResourceFetcher: Resource downloaded: ' + resource.id);
|
||||||
completeDownload();
|
await completeDownload(true, localResourceContentPath);
|
||||||
}).catch(async (error) => {
|
}).catch(async (error) => {
|
||||||
this.logger().error('ResourceFetcher: Could not download resource: ' + resource.id, error);
|
this.logger().error('ResourceFetcher: Could not download resource: ' + resource.id, error);
|
||||||
await Resource.setLocalState(resource, { fetch_status: Resource.FETCH_STATUS_ERROR, fetch_error: error.message });
|
await Resource.setLocalState(resource, { fetch_status: Resource.FETCH_STATUS_ERROR, fetch_error: error.message });
|
||||||
completeDownload();
|
await completeDownload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user