1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-03-20 20:55:18 +02:00

All: Various changes to get filesystem target to work on mobile

This commit is contained in:
Laurent Cozic 2018-01-17 21:01:41 +00:00
parent c16ea6b237
commit 9efbf74b6f
6 changed files with 86 additions and 29 deletions

View File

@ -24,9 +24,12 @@ class SyncTargetFilesystem extends BaseSyncTarget {
} }
async initFileApi() { async initFileApi() {
const fileApi = new FileApi(Setting.value('sync.2.path'), new FileApiDriverLocal()); const syncPath = Setting.value('sync.2.path');
const driver = new FileApiDriverLocal();
const fileApi = new FileApi(syncPath, driver);
fileApi.setLogger(this.logger()); fileApi.setLogger(this.logger());
fileApi.setSyncTargetId(SyncTargetFilesystem.id()); fileApi.setSyncTargetId(SyncTargetFilesystem.id());
await driver.mkdir(syncPath);
return fileApi; return fileApi;
} }

View File

@ -1,6 +1,3 @@
const fs = require('fs-extra');
const { promiseChain } = require('lib/promise-utils.js');
const moment = require('moment');
const BaseItem = require('lib/models/BaseItem.js'); const BaseItem = require('lib/models/BaseItem.js');
const { time } = require('lib/time-utils.js'); const { time } = require('lib/time-utils.js');
@ -19,8 +16,9 @@ const { time } = require('lib/time-utils.js');
class FileApiDriverLocal { class FileApiDriverLocal {
fsErrorToJsError_(error) { fsErrorToJsError_(error, path = null) {
let msg = error.toString(); let msg = error.toString();
if (path !== null) msg += '. Path: ' + path;
let output = new Error(msg); let output = new Error(msg);
if (error.code) output.code = error.code; if (error.code) output.code = error.code;
return output; return output;
@ -34,9 +32,9 @@ class FileApiDriverLocal {
async stat(path) { async stat(path) {
try { try {
const s = await this.fsDriver().stat(path); const s = await this.fsDriver().stat(path);
if (!s) return null;
return this.metadataFromStat_(s); return this.metadataFromStat_(s);
} catch (error) { } catch (error) {
if (error.code == 'ENOENT') return null;
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error);
} }
} }
@ -106,7 +104,7 @@ class FileApiDriverLocal {
items: output, items: output,
}; };
} catch(error) { } catch(error) {
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error, path);
} }
} }
@ -121,7 +119,7 @@ class FileApiDriverLocal {
context: null, context: null,
}; };
} catch(error) { } catch(error) {
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error, path);
} }
} }
@ -138,19 +136,20 @@ class FileApiDriverLocal {
} }
} catch (error) { } catch (error) {
if (error.code == 'ENOENT') return null; if (error.code == 'ENOENT') return null;
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error, path);
} }
return output; return output;
} }
async mkdir(path) { async mkdir(path) {
console.info('EXISTST ' + path, await this.fsDriver().exists(path));
if (await this.fsDriver().exists(path)) return; if (await this.fsDriver().exists(path)) return;
try { try {
await this.fsDriver().mkdir(path); await this.fsDriver().mkdir(path);
} catch (error) { } catch (error) {
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error, path);
} }
// return new Promise((resolve, reject) => { // return new Promise((resolve, reject) => {
@ -182,7 +181,7 @@ class FileApiDriverLocal {
await this.fsDriver().writeFile(path, content, 'utf8'); await this.fsDriver().writeFile(path, content, 'utf8');
} catch (error) { } catch (error) {
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error, path);
} }
// if (!options) options = {}; // if (!options) options = {};
@ -204,7 +203,7 @@ class FileApiDriverLocal {
try { try {
await this.fsDriver().unlink(path); await this.fsDriver().unlink(path);
} catch (error) { } catch (error) {
throw this.fsErrorToJsError_(error); throw this.fsErrorToJsError_(error, path);
} }
// return new Promise((resolve, reject) => { // return new Promise((resolve, reject) => {
@ -224,7 +223,11 @@ class FileApiDriverLocal {
} }
async move(oldPath, newPath) { async move(oldPath, newPath) {
return this.fsDriver().move(oldPath, newPath); try {
await this.fsDriver().move(oldPath, newPath);
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
// let lastError = null; // let lastError = null;

View File

@ -35,7 +35,7 @@ class FsDriverNode {
await time.sleep(1); await time.sleep(1);
continue; continue;
} }
throw this.fsErrorToJsError_(error); throw error;
} }
} }
@ -51,9 +51,14 @@ class FsDriverNode {
} }
async stat(path) { async stat(path) {
const s = await fs.stat(path); try {
s.path = path; const s = await fs.stat(path);
return s; s.path = path;
return s;
} catch (error) {
if (error.code == 'ENOENT') return null;
throw error;
}
} }
async setTimestamp(path, timestampDate) { async setTimestamp(path, timestampDate) {

View File

@ -18,6 +18,38 @@ class FsDriverRN {
throw new Error('Not implemented'); throw new Error('Not implemented');
} }
// Returns a format compatible with Node.js format
rnfsStatToStd_(stat, path) {
return {
birthtime: stat.ctime ? stat.ctime : stat.mtime, // Confusingly, "ctime" normally means "change time" but here it's used as "creation time". Also sometimes it is null
mtime: stat.mtime,
isDirectory: () => stat.isDirectory(),
path: path,
size: stat.size,
};
}
async readDirStats(path) {
let items = await RNFS.readDir(path);
let output = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
console.info('ITEM', item);
const relativePath = item.path.substr(path.length + 1);
output.push(this.rnfsStatToStd_(item, relativePath));
// let stat = await this.stat(path + '/' + items[i]);
// if (!stat) continue; // Has been deleted between the readdir() call and now
// stat.path = stat.path.substr(path.length + 1);
// output.push(stat);
}
console.info('READ DIR', path);
console.info(output);
return output;
}
async move(source, dest) { async move(source, dest) {
return RNFS.moveFile(source, dest); return RNFS.moveFile(source, dest);
} }
@ -27,22 +59,30 @@ class FsDriverRN {
} }
async mkdir(path) { async mkdir(path) {
return fs.mkdir(path); return RNFS.mkdir(path);
} }
async stat(path) { async stat(path) {
const r = await RNFS.stat(path); try {
// Returns a format compatible with Node.js format const r = await RNFS.stat(path);
return { return this.rnfsStatToStd_(r, path);
birthtime: r.ctime, // Confusingly, "ctime" normally means "change time" but here it's used as "creation time" } catch (error) {
mtime: r.mtime, if (error && error.message && error.message.indexOf('exist') >= 0) {
isDirectory: () => r.isDirectory(), // Probably { [Error: File does not exist] framesToPop: 1, code: 'EUNSPECIFIED' }
path: path, // which unfortunately does not have a proper error code. Can be ignored.
}; return null;
} else {
throw error;
}
}
} }
// NOTE: DOES NOT WORK - no error is thrown and the function is called with the right
// arguments but the function returns `false` and the timestamp is not set.
// Current setTimestamp is not really used so keep it that way, but careful if it
// becomes needed.
async setTimestamp(path, timestampDate) { async setTimestamp(path, timestampDate) {
return RNFS.touch(path, timestampDate); // return RNFS.touch(path, timestampDate, timestampDate);
} }
async open(path, mode) { async open(path, mode) {

View File

@ -18,7 +18,7 @@ class Synchronizer {
this.state_ = 'idle'; this.state_ = 'idle';
this.db_ = db; this.db_ = db;
this.api_ = api; this.api_ = api;
this.syncDirName_ = '.sync'; //this.syncDirName_ = '.sync';
this.resourceDirName_ = '.resource'; this.resourceDirName_ = '.resource';
this.logger_ = new Logger(); this.logger_ = new Logger();
this.appType_ = appType; this.appType_ = appType;
@ -197,7 +197,7 @@ class Synchronizer {
this.logSyncOperation('starting', null, null, 'Starting synchronisation to target ' + syncTargetId + '... [' + synchronizationId + ']'); this.logSyncOperation('starting', null, null, 'Starting synchronisation to target ' + syncTargetId + '... [' + synchronizationId + ']');
try { try {
await this.api().mkdir(this.syncDirName_); //await this.api().mkdir(this.syncDirName_);
await this.api().mkdir(this.resourceDirName_); await this.api().mkdir(this.resourceDirName_);
let donePaths = []; let donePaths = [];

View File

@ -44,14 +44,19 @@ const { _, setLocale, closestSupportedLocale, defaultLocale } = require('lib/loc
const RNFetchBlob = require('react-native-fetch-blob').default; const RNFetchBlob = require('react-native-fetch-blob').default;
const { PoorManIntervals } = require('lib/poor-man-intervals.js'); const { PoorManIntervals } = require('lib/poor-man-intervals.js');
const { reducer, defaultState } = require('lib/reducer.js'); const { reducer, defaultState } = require('lib/reducer.js');
const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
const DropdownAlert = require('react-native-dropdownalert').default; const DropdownAlert = require('react-native-dropdownalert').default;
const SyncTargetRegistry = require('lib/SyncTargetRegistry.js'); const SyncTargetRegistry = require('lib/SyncTargetRegistry.js');
const SyncTargetOneDrive = require('lib/SyncTargetOneDrive.js'); const SyncTargetOneDrive = require('lib/SyncTargetOneDrive.js');
const SyncTargetFilesystem = require('lib/SyncTargetFilesystem.js');
const SyncTargetOneDriveDev = require('lib/SyncTargetOneDriveDev.js'); const SyncTargetOneDriveDev = require('lib/SyncTargetOneDriveDev.js');
SyncTargetRegistry.addClass(SyncTargetOneDrive); SyncTargetRegistry.addClass(SyncTargetOneDrive);
SyncTargetRegistry.addClass(SyncTargetOneDriveDev); SyncTargetRegistry.addClass(SyncTargetOneDriveDev);
// Disabled because not fully working
//SyncTargetRegistry.addClass(SyncTargetFilesystem);
const FsDriverRN = require('lib/fs-driver-rn.js').FsDriverRN; const FsDriverRN = require('lib/fs-driver-rn.js').FsDriverRN;
const DecryptionWorker = require('lib/services/DecryptionWorker'); const DecryptionWorker = require('lib/services/DecryptionWorker');
const EncryptionService = require('lib/services/EncryptionService'); const EncryptionService = require('lib/services/EncryptionService');
@ -341,6 +346,7 @@ async function initialize(dispatch) {
const fsDriver = new FsDriverRN(); const fsDriver = new FsDriverRN();
Resource.fsDriver_ = fsDriver; Resource.fsDriver_ = fsDriver;
FileApiDriverLocal.fsDriver_ = fsDriver;
AlarmService.setDriver(new AlarmServiceDriver()); AlarmService.setDriver(new AlarmServiceDriver());
AlarmService.setLogger(mainLogger); AlarmService.setLogger(mainLogger);