1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-23 18:53:36 +02:00

Fixed RN sync issue

This commit is contained in:
Laurent Cozic 2017-07-06 19:48:17 +00:00
parent 5802adc9f1
commit 40ed3216a3
7 changed files with 4393 additions and 33 deletions

View File

@ -16,6 +16,7 @@ import { Resource } from 'lib/models/resource.js';
import { BaseItem } from 'lib/models/base-item.js'; import { BaseItem } from 'lib/models/base-item.js';
import { Note } from 'lib/models/note.js'; import { Note } from 'lib/models/note.js';
import { Tag } from 'lib/models/tag.js'; import { Tag } from 'lib/models/tag.js';
import { NoteTag } from 'lib/models/note-tag.js';
import { Setting } from 'lib/models/setting.js'; import { Setting } from 'lib/models/setting.js';
import { Synchronizer } from 'lib/synchronizer.js'; import { Synchronizer } from 'lib/synchronizer.js';
import { Logger } from 'lib/logger.js'; import { Logger } from 'lib/logger.js';
@ -23,6 +24,7 @@ import { uuid } from 'lib/uuid.js';
import { sprintf } from 'sprintf-js'; import { sprintf } from 'sprintf-js';
import { importEnex } from 'import-enex'; import { importEnex } from 'import-enex';
import { vorpalUtils } from 'vorpal-utils.js'; import { vorpalUtils } from 'vorpal-utils.js';
import { reg } from 'lib/registry.js';
import { FsDriverNode } from './fs-driver-node.js'; import { FsDriverNode } from './fs-driver-node.js';
import { filename, basename } from 'lib/path-utils.js'; import { filename, basename } from 'lib/path-utils.js';
import { _ } from 'lib/locale.js'; import { _ } from 'lib/locale.js';
@ -677,11 +679,7 @@ async function synchronizer(syncTarget) {
let fileApi = null; let fileApi = null;
if (syncTarget == 'onedrive') { if (syncTarget == 'onedrive') {
let oneDriveApi = oneDriveApi.instance(); const oneDriveApi = reg.oneDriveApi();
// const CLIENT_ID = 'e09fc0de-c958-424f-83a2-e56a721d331b';
// const CLIENT_SECRET = 'JA3cwsqSGHFtjMwd5XoF5L5';
//let driver = new FileApiDriverOneDrive(CLIENT_ID, CLIENT_SECRET);
let driver = new FileApiDriverOneDrive(oneDriveApi); let driver = new FileApiDriverOneDrive(oneDriveApi);
let auth = Setting.value('sync.onedrive.auth'); let auth = Setting.value('sync.onedrive.auth');
@ -693,11 +691,6 @@ async function synchronizer(syncTarget) {
Setting.setValue('sync.onedrive.auth', JSON.stringify(auth)); Setting.setValue('sync.onedrive.auth', JSON.stringify(auth));
} }
//oneDriveApi.setAuth(auth);
oneDriveApi.on('authRefreshed', (a) => {
Setting.setValue('sync.onedrive.auth', JSON.stringify(a));
});
let appDir = await oneDriveApi.appDirectory(); let appDir = await oneDriveApi.appDirectory();
logger.info('App dir: ' + appDir); logger.info('App dir: ' + appDir);
fileApi = new FileApi(appDir, driver); fileApi = new FileApi(appDir, driver);
@ -939,6 +932,14 @@ async function main() {
logger.info(sprintf('Starting %s %s...', packageJson.name, packageJson.version)); logger.info(sprintf('Starting %s %s...', packageJson.name, packageJson.version));
logger.info('Profile directory: ' + profileDir); logger.info('Profile directory: ' + profileDir);
// That's not good, but it's to avoid circular dependency issues
// in the BaseItem class.
BaseItem.loadClass('Note', Note);
BaseItem.loadClass('Folder', Folder);
BaseItem.loadClass('Resource', Resource);
BaseItem.loadClass('Tag', Tag);
BaseItem.loadClass('NoteTag', NoteTag);
database_ = new Database(new DatabaseDriverNode()); database_ = new Database(new DatabaseDriverNode());
database_.setLogger(dbLogger); database_.setLogger(dbLogger);
await database_.open({ name: profileDir + '/database.sqlite' }); await database_.open({ name: profileDir + '/database.sqlite' });

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,8 @@ import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js'; import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js'; import { Note } from 'lib/models/note.js';
import { Resource } from 'lib/models/resource.js'; import { Resource } from 'lib/models/resource.js';
import { Tag } from 'lib/models/tag.js';
import { NoteTag } from 'lib/models/note-tag.js';
import { Logger } from 'lib/logger.js'; import { Logger } from 'lib/logger.js';
import { Setting } from 'lib/models/setting.js'; import { Setting } from 'lib/models/setting.js';
import { BaseItem } from 'lib/models/base-item.js'; import { BaseItem } from 'lib/models/base-item.js';
@ -25,9 +27,14 @@ Resource.fsDriver_ = fsDriver;
const logger = new Logger(); const logger = new Logger();
logger.addTarget('file', { path: __dirname + '/../tests/logs/log.txt' }); logger.addTarget('file', { path: __dirname + '/../tests/logs/log.txt' });
//logger.addTarget('console');
logger.setLevel(Logger.LEVEL_DEBUG); logger.setLevel(Logger.LEVEL_DEBUG);
BaseItem.loadClass('Note', Note);
BaseItem.loadClass('Folder', Folder);
BaseItem.loadClass('Resource', Resource);
BaseItem.loadClass('Tag', Tag);
BaseItem.loadClass('NoteTag', NoteTag);
function sleep(n) { function sleep(n) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
setTimeout(() => { setTimeout(() => {

View File

@ -9,14 +9,33 @@ class BaseItem extends BaseModel {
return true; return true;
} }
static loadClass(className, classRef) {
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
if (BaseItem.syncItemDefinitions_[i].className == className) {
BaseItem.syncItemDefinitions_[i].classRef = classRef;
return;
}
}
throw new Error('Invalid class name: ' + className);
}
// Need to dynamically load the classes like this to avoid circular dependencies // Need to dynamically load the classes like this to avoid circular dependencies
static getClass(name) { static getClass(name) {
if (!this.classes_) this.classes_ = {}; for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
if (this.classes_[name]) return this.classes_[name]; if (BaseItem.syncItemDefinitions_[i].className == name) {
let filename = name.toLowerCase(); return BaseItem.syncItemDefinitions_[i].classRef;
if (name == 'NoteTag') filename = 'note-tag'; }
this.classes_[name] = require('lib/models/' + filename + '.js')[name]; }
return this.classes_[name];
throw new Error('Invalid class name: ' + name);
// if (!this.classes_) this.classes_ = {};
// if (this.classes_[name]) return this.classes_[name];
// let filename = name.toLowerCase();
// if (name == 'NoteTag') filename = 'note-tag';
// this.classes_[name] = require('lib/models/' + filename + '.js')[name];
// return this.classes_[name];
} }
static systemPath(itemOrId) { static systemPath(itemOrId) {
@ -229,6 +248,12 @@ class BaseItem extends BaseModel {
} }
// import { Note } from 'lib/models/note.js';
// import { Folder } from 'lib/models/folder.js';
// import { Resource } from 'lib/models/resource.js';
// import { Tag } from 'lib/models/tag.js';
// import { NoteTag } from 'lib/models/note-tag.js';
// Also update: // Also update:
// - itemsThatNeedSync() // - itemsThatNeedSync()
// - syncedItems() // - syncedItems()

View File

@ -1,5 +1,6 @@
import { shim } from 'lib/shim.js'; import { shim } from 'lib/shim.js';
import { stringify } from 'query-string'; import { stringify } from 'query-string';
import { time } from 'lib/time-utils.js';
class OneDriveApi { class OneDriveApi {
@ -133,15 +134,6 @@ class OneDriveApi {
if (data) options.body = data; if (data) options.body = data;
// Rare error (one Google hit) - maybe repeat the request when it happens?
// { error:
// { code: 'generalException',
// message: 'An error occurred in the data store.',
// innerError:
// { 'request-id': 'b4310552-c18a-45b1-bde1-68e2c2345eef',
// date: '2017-06-29T00:15:50' } } }
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
options.headers['Authorization'] = 'bearer ' + this.token(); options.headers['Authorization'] = 'bearer ' + this.token();
@ -153,6 +145,26 @@ class OneDriveApi {
if (error.code == 'InvalidAuthenticationToken') { if (error.code == 'InvalidAuthenticationToken') {
await this.refreshAccessToken(); await this.refreshAccessToken();
continue; continue;
} else if (error && ((error.error && error.error.code == 'generalException') || (error.code == 'generalException'))) {
// Rare error (one Google hit) - I guess the request can be repeated
// { error:
// { code: 'generalException',
// message: 'An error occurred in the data store.',
// innerError:
// { 'request-id': 'b4310552-c18a-45b1-bde1-68e2c2345eef',
// date: '2017-06-29T00:15:50' } } }
await time.msleep(1000 * i);
continue;
} else if (error.code == 'EAGAIN') {
// { FetchError: request to https://graph.microsoft.com/v1.0/drive/root:/Apps/Joplin/.sync/7ee5dc04afcb414aa7c684bfc1edba8b.md_1499352102856 failed, reason: connect EAGAIN 65.52.64.250:443 - Local (0.0.0.0:54374)
// name: 'FetchError',
// message: 'request to https://graph.microsoft.com/v1.0/drive/root:/Apps/Joplin/.sync/7ee5dc04afcb414aa7c684bfc1edba8b.md_1499352102856 failed, reason: connect EAGAIN 65.52.64.250:443 - Local (0.0.0.0:54374)',
// type: 'system',
// errno: 'EAGAIN',
// code: 'EAGAIN' }
await time.msleep(1000 * i);
continue;
} else { } else {
error.request = method + ' ' + url + ' ' + JSON.stringify(query) + ' ' + JSON.stringify(data) + ' ' + JSON.stringify(options); error.request = method + ' ' + url + ' ' + JSON.stringify(query) + ' ' + JSON.stringify(data) + ' ' + JSON.stringify(options);
throw error; throw error;

View File

@ -313,12 +313,12 @@ class Synchronizer {
}; };
if (action == 'createLocal') options.isNew = true; if (action == 'createLocal') options.isNew = true;
if (newContent.type_ == BaseModel.TYPE_RESOURCE && action == 'createLocal') { // if (newContent.type_ == BaseModel.TYPE_RESOURCE && action == 'createLocal') {
let localResourceContentPath = Resource.fullPath(newContent); // let localResourceContentPath = Resource.fullPath(newContent);
let remoteResourceContentPath = this.resourceDirName_ + '/' + newContent.id; // let remoteResourceContentPath = this.resourceDirName_ + '/' + newContent.id;
let remoteResourceContent = await this.api().get(remoteResourceContentPath, { encoding: 'binary' }); // let remoteResourceContent = await this.api().get(remoteResourceContentPath, { encoding: 'binary' });
await Resource.setContent(newContent, remoteResourceContent); // await Resource.setContent(newContent, remoteResourceContent);
} // }
await ItemClass.save(newContent, options); await ItemClass.save(newContent, options);

View File

@ -9,6 +9,10 @@ import { addNavigationHelpers } from 'react-navigation';
import { Log } from 'lib/log.js' import { Log } from 'lib/log.js'
import { Note } from 'lib/models/note.js' import { Note } from 'lib/models/note.js'
import { Folder } from 'lib/models/folder.js' import { Folder } from 'lib/models/folder.js'
import { Resource } from 'lib/models/resource.js'
import { Tag } from 'lib/models/tag.js'
import { NoteTag } from 'lib/models/note-tag.js'
import { BaseItem } from 'lib/models/base-item.js'
import { BaseModel } from 'lib/base-model.js' import { BaseModel } from 'lib/base-model.js'
import { Database } from 'lib/database.js' import { Database } from 'lib/database.js'
import { ItemList } from 'lib/components/item-list.js' import { ItemList } from 'lib/components/item-list.js'
@ -199,7 +203,13 @@ class AppComponent extends React.Component {
NotesScreenUtils.dispatch = this.props.dispatch; NotesScreenUtils.dispatch = this.props.dispatch;
BaseModel.db_ = db; BaseModel.db_ = db;
db.open({ name: '/storage/emulated/0/Download/joplin-43.sqlite' }).then(() => { BaseItem.loadClass('Note', Note);
BaseItem.loadClass('Folder', Folder);
BaseItem.loadClass('Resource', Resource);
BaseItem.loadClass('Tag', Tag);
BaseItem.loadClass('NoteTag', NoteTag);
db.open({ name: '/storage/emulated/0/Download/joplin-44.sqlite' }).then(() => {
Log.info('Database is ready.'); Log.info('Database is ready.');
}).then(() => { }).then(() => {
Log.info('Loading settings...'); Log.info('Loading settings...');