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() {
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.setSyncTargetId(SyncTargetFilesystem.id());
await driver.mkdir(syncPath);
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 { time } = require('lib/time-utils.js');
@ -19,8 +16,9 @@ const { time } = require('lib/time-utils.js');
class FileApiDriverLocal {
fsErrorToJsError_(error) {
fsErrorToJsError_(error, path = null) {
let msg = error.toString();
if (path !== null) msg += '. Path: ' + path;
let output = new Error(msg);
if (error.code) output.code = error.code;
return output;
@ -34,9 +32,9 @@ class FileApiDriverLocal {
async stat(path) {
try {
const s = await this.fsDriver().stat(path);
if (!s) return null;
return this.metadataFromStat_(s);
} catch (error) {
if (error.code == 'ENOENT') return null;
throw this.fsErrorToJsError_(error);
}
}
@ -106,7 +104,7 @@ class FileApiDriverLocal {
items: output,
};
} catch(error) {
throw this.fsErrorToJsError_(error);
throw this.fsErrorToJsError_(error, path);
}
}
@ -121,7 +119,7 @@ class FileApiDriverLocal {
context: null,
};
} catch(error) {
throw this.fsErrorToJsError_(error);
throw this.fsErrorToJsError_(error, path);
}
}
@ -138,19 +136,20 @@ class FileApiDriverLocal {
}
} catch (error) {
if (error.code == 'ENOENT') return null;
throw this.fsErrorToJsError_(error);
throw this.fsErrorToJsError_(error, path);
}
return output;
}
async mkdir(path) {
console.info('EXISTST ' + path, await this.fsDriver().exists(path));
if (await this.fsDriver().exists(path)) return;
try {
await this.fsDriver().mkdir(path);
} catch (error) {
throw this.fsErrorToJsError_(error);
throw this.fsErrorToJsError_(error, path);
}
// return new Promise((resolve, reject) => {
@ -182,7 +181,7 @@ class FileApiDriverLocal {
await this.fsDriver().writeFile(path, content, 'utf8');
} catch (error) {
throw this.fsErrorToJsError_(error);
throw this.fsErrorToJsError_(error, path);
}
// if (!options) options = {};
@ -204,7 +203,7 @@ class FileApiDriverLocal {
try {
await this.fsDriver().unlink(path);
} catch (error) {
throw this.fsErrorToJsError_(error);
throw this.fsErrorToJsError_(error, path);
}
// return new Promise((resolve, reject) => {
@ -224,7 +223,11 @@ class FileApiDriverLocal {
}
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;

View File

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

View File

@ -18,6 +18,38 @@ class FsDriverRN {
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) {
return RNFS.moveFile(source, dest);
}
@ -27,22 +59,30 @@ class FsDriverRN {
}
async mkdir(path) {
return fs.mkdir(path);
return RNFS.mkdir(path);
}
async stat(path) {
const r = await RNFS.stat(path);
// Returns a format compatible with Node.js format
return {
birthtime: r.ctime, // Confusingly, "ctime" normally means "change time" but here it's used as "creation time"
mtime: r.mtime,
isDirectory: () => r.isDirectory(),
path: path,
};
try {
const r = await RNFS.stat(path);
return this.rnfsStatToStd_(r, path);
} catch (error) {
if (error && error.message && error.message.indexOf('exist') >= 0) {
// Probably { [Error: File does not exist] framesToPop: 1, code: 'EUNSPECIFIED' }
// 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) {
return RNFS.touch(path, timestampDate);
// return RNFS.touch(path, timestampDate, timestampDate);
}
async open(path, mode) {

View File

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

View File

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