mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Added cp command
This commit is contained in:
parent
4fa65de31d
commit
8c5f0622a2
@ -42,7 +42,7 @@ class Application {
|
||||
updatePrompt() {
|
||||
if (!this.showPromptString_) return '';
|
||||
|
||||
let path = '~';
|
||||
let path = '';
|
||||
if (this.currentFolder()) {
|
||||
path += '/' + this.currentFolder().title;
|
||||
}
|
||||
@ -57,45 +57,38 @@ class Application {
|
||||
this.updatePrompt();
|
||||
}
|
||||
|
||||
async parseNotePattern(pattern) {
|
||||
if (pattern.indexOf('..') === 0) {
|
||||
let pieces = pattern.split('/');
|
||||
if (pieces.length != 3) throw new Error(_('Invalid pattern: %s', pattern));
|
||||
let parent = await this.loadItem(BaseModel.TYPE_FOLDER, pieces[1]);
|
||||
if (!parent) throw new Error(_('Notebook not found: %s', pieces[1]));
|
||||
return {
|
||||
parent: parent,
|
||||
title: pieces[2],
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
parent: null,
|
||||
title: pattern,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async loadItem(type, pattern) {
|
||||
let output = await this.loadItems(type, pattern);
|
||||
return output.length ? output[0] : null;
|
||||
}
|
||||
|
||||
async loadItems(type, pattern) {
|
||||
let ItemClass = BaseItem.itemClass(type);
|
||||
let item = null;
|
||||
if (type == BaseModel.TYPE_NOTE) {
|
||||
if (!app().currentFolder()) throw new Error(_('No notebook has been created.'));
|
||||
item = await ItemClass.loadFolderNoteByField(app().currentFolder().id, 'title', pattern);
|
||||
} else {
|
||||
item = await ItemClass.loadByTitle(pattern);
|
||||
async loadItems(type, pattern, options = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
const parent = options.parent ? options.parent : app().currentFolder();
|
||||
const ItemClass = BaseItem.itemClass(type);
|
||||
|
||||
if (type == BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) { // Handle it as pattern
|
||||
if (!parent) throw new Error(_('No notebook selected.'));
|
||||
return await Note.previews(parent.id, { titlePattern: pattern });
|
||||
} else { // Single item
|
||||
let item = null;
|
||||
if (type == BaseModel.TYPE_NOTE) {
|
||||
if (!parent) throw new Error(_('No notebook has been specified.'));
|
||||
item = await ItemClass.loadFolderNoteByField(parent.id, 'title', pattern);
|
||||
} else {
|
||||
item = await ItemClass.loadByTitle(pattern);
|
||||
}
|
||||
if (item) return [item];
|
||||
|
||||
item = await ItemClass.load(pattern); // Load by id
|
||||
if (item) return [item];
|
||||
|
||||
if (pattern.length >= 4) {
|
||||
item = await ItemClass.loadByPartialId(pattern);
|
||||
if (item) return [item];
|
||||
}
|
||||
}
|
||||
if (item) return [item];
|
||||
|
||||
item = await ItemClass.load(pattern); // Load by id
|
||||
if (item) return [item];
|
||||
|
||||
item = await ItemClass.loadByPartialId(pattern);
|
||||
if (item) return [item];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -23,22 +23,10 @@ class Command extends BaseCommand {
|
||||
async action(args) {
|
||||
let title = args['title'];
|
||||
|
||||
let item = null;
|
||||
if (!app().currentFolder()) {
|
||||
item = await Folder.loadByField('title', title);
|
||||
} else {
|
||||
item = await app().loadItem(BaseModel.TYPE_NOTE, title);
|
||||
}
|
||||
|
||||
if (!item) throw new Error(_('No item with title "%s" found.', title));
|
||||
|
||||
let content = null;
|
||||
if (!app().currentFolder()) {
|
||||
content = await Folder.serialize(item);
|
||||
} else {
|
||||
content = await Note.serialize(item);
|
||||
}
|
||||
let item = await app().loadItem(BaseModel.TYPE_NOTE, title);
|
||||
if (!item) throw new Error(_('No item "%s" found.', title));
|
||||
|
||||
const content = await Note.serialize(item);
|
||||
this.log(content);
|
||||
}
|
||||
|
||||
|
48
CliClient/app/command-cp.js
Normal file
48
CliClient/app/command-cp.js
Normal file
@ -0,0 +1,48 @@
|
||||
import { BaseCommand } from './base-command.js';
|
||||
import { app } from './app.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { BaseModel } from 'lib/base-model.js';
|
||||
import { Folder } from 'lib/models/folder.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { autocompleteItems } from './autocomplete.js';
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'cp <pattern> [notebook]';
|
||||
}
|
||||
|
||||
description() {
|
||||
return 'Duplicates the notes matching <pattern> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.';
|
||||
}
|
||||
|
||||
autocomplete() {
|
||||
return { data: autocompleteItems };
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let folder = null;
|
||||
if (args['notebook']) {
|
||||
folder = await app().loadItem(BaseModel.TYPE_FOLDER, args['notebook']);
|
||||
} else {
|
||||
folder = app().currentFolder();
|
||||
}
|
||||
|
||||
if (!folder) throw new Error(_('No notebook "%s"', args['notebook']));
|
||||
|
||||
const notes = await app().loadItems(BaseModel.TYPE_NOTE, args['pattern']);
|
||||
if (!notes.length) throw new Error(_('No note matches this pattern: "%s"', args['pattern']));
|
||||
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
const newNote = await Note.duplicate(notes[i].id, {
|
||||
changes: {
|
||||
parent_id: folder.id
|
||||
},
|
||||
});
|
||||
Note.updateGeolocation(newNote.id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
@ -13,7 +13,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
description() {
|
||||
return 'Displays the notes in [notebook]. Use `ls ..` to display the list of notebooks.';
|
||||
return 'Displays the notes in [notebook]. Use `ls /` to display the list of notebooks.';
|
||||
}
|
||||
|
||||
options() {
|
||||
@ -51,7 +51,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
if (pattern) queryOptions.titlePattern = pattern;
|
||||
|
||||
if (pattern == '..' || !app().currentFolder()) {
|
||||
if (pattern == '/' || !app().currentFolder()) {
|
||||
items = await Folder.all(queryOptions);
|
||||
suffix = '/';
|
||||
} else {
|
||||
|
@ -20,11 +20,9 @@ class Command extends BaseCommand {
|
||||
async action(args) {
|
||||
if (!app().currentFolder()) throw new Error(_('Notes can only be created within a notebook.'));
|
||||
|
||||
let path = await app().parseNotePattern(args['note']);
|
||||
|
||||
let note = {
|
||||
title: path.title,
|
||||
parent_id: path.parent ? path.parent.id : app().currentFolder().id,
|
||||
title: args.note,
|
||||
parent_id: app().currentFolder().id,
|
||||
};
|
||||
|
||||
note = await Note.save(note);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { BaseCommand } from './base-command.js';
|
||||
import { app } from './app.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { BaseModel } from 'lib/base-model.js';
|
||||
import { Folder } from 'lib/models/folder.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { autocompleteItems } from './autocomplete.js';
|
||||
@ -20,13 +21,12 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
if (!app().currentFolder()) throw new Error(_('Please select a notebook first.'));
|
||||
const pattern = args['pattern'];
|
||||
|
||||
let pattern = args['pattern'];
|
||||
const folder = await Folder.loadByField('title', args['notebook']);
|
||||
if (!folder) throw new Error(_('No notebook "%s"', args['notebook']));
|
||||
|
||||
let folder = await Folder.loadByField('title', args['notebook']);
|
||||
if (!folder) throw new Error(_('No folder with title "%s"', args['notebook']));
|
||||
let notes = await Note.previews(app().currentFolder().id, { titlePattern: pattern });
|
||||
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
|
||||
if (!notes.length) throw new Error(_('No note matches this pattern: "%s"', pattern));
|
||||
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
|
@ -15,7 +15,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
description() {
|
||||
return 'Deletes the given item. For a notebook, all the notes within that notebook will be deleted. Use `rm ../<notebook>` to delete a notebook.';
|
||||
return 'Deletes the items matching <pattern>.';
|
||||
}
|
||||
|
||||
autocomplete() {
|
||||
@ -25,44 +25,28 @@ class Command extends BaseCommand {
|
||||
options() {
|
||||
return [
|
||||
['-f, --force', 'Deletes the items without asking for confirmation.'],
|
||||
['-r, --recursive', 'Deletes a notebook.'],
|
||||
];
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let pattern = args['pattern'].toString();
|
||||
let itemType = null;
|
||||
let force = args.options && args.options.force === true;
|
||||
const pattern = args['pattern'].toString();
|
||||
const recursive = args.options && args.options.recursive === true;
|
||||
const force = args.options && args.options.force === true;
|
||||
|
||||
if (pattern.indexOf('*') < 0) { // Handle it as a simple title
|
||||
if (pattern.substr(0, 3) == '../') {
|
||||
itemType = BaseModel.TYPE_FOLDER;
|
||||
pattern = pattern.substr(3);
|
||||
} else {
|
||||
itemType = BaseModel.TYPE_NOTE;
|
||||
}
|
||||
|
||||
let item = item = await app().loadItem(itemType, pattern); // await BaseItem.loadItemByField(itemType, 'title', pattern);
|
||||
if (!item) throw new Error(_('No item "%s" found.', pattern));
|
||||
|
||||
let ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('Delete "%s"?', item.title));
|
||||
if (ok) {
|
||||
await BaseItem.deleteItem(itemType, item.id);
|
||||
if (app().currentFolder() && app().currentFolder().id == item.id) {
|
||||
let f = await Folder.defaultFolder();
|
||||
app().switchCurrentFolder(f);
|
||||
}
|
||||
}
|
||||
} else { // Handle it as a glob pattern
|
||||
if (app().currentFolder()) {
|
||||
let notes = await Note.previews(app().currentFolder().id, { titlePattern: pattern });
|
||||
if (!notes.length) throw new Error(_('No note matches this pattern: "%s"', pattern));
|
||||
let ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('%d notes match this pattern. Delete them?', notes.length));
|
||||
if (ok) {
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Note.delete(notes[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (recursive) {
|
||||
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
|
||||
if (!folder) throw new Error(_('No notebook matchin pattern "%s"', pattern));
|
||||
const ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('Delete notebook "%s"?', folder.title));
|
||||
if (!ok) return;
|
||||
await Folder.delete(folder.id);
|
||||
} else {
|
||||
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
|
||||
if (!notes.length) throw new Error(_('No note matchin pattern "%s"', pattern));
|
||||
const ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('%d notes match this pattern. Delete them?', notes.length));
|
||||
if (!ok) return;
|
||||
let ids = notes.map((n) => n.id);
|
||||
await Note.batchDelete(ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { BaseCommand } from './base-command.js';
|
||||
import { app } from './app.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { BaseModel } from 'lib/base-model.js';
|
||||
import { Folder } from 'lib/models/folder.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { BaseItem } from 'lib/models/base-item.js';
|
||||
@ -9,11 +10,11 @@ import { autocompleteItems } from './autocomplete.js';
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'set <item> <name> [value]';
|
||||
return 'set <note> <name> [value]';
|
||||
}
|
||||
|
||||
description() {
|
||||
return 'Sets the property <name> of the given <item> to the given [value].';
|
||||
return 'Sets the property <name> of the given <note> to the given [value].';
|
||||
}
|
||||
|
||||
autocomplete() {
|
||||
@ -21,31 +22,22 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let title = args['item'];
|
||||
let title = args['note'];
|
||||
let propName = args['name'];
|
||||
let propValue = args['value'];
|
||||
if (!propValue) propValue = '';
|
||||
|
||||
let item = null;
|
||||
if (!app().currentFolder()) {
|
||||
item = await Folder.loadByField('title', title);
|
||||
} else {
|
||||
item = await Note.loadFolderNoteByField(app().currentFolder().id, 'title', title);
|
||||
let notes = await app().loadItems(BaseModel.TYPE_NOTE, title);
|
||||
if (!notes.length) throw new Error(_('No note "%s" found.', title));
|
||||
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
let newNote = {
|
||||
id: notes[i].id,
|
||||
type_: notes[i].type_,
|
||||
};
|
||||
newNote[propName] = propValue;
|
||||
await Note.save(newNote);
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
item = await BaseItem.loadItemById(title);
|
||||
}
|
||||
|
||||
if (!item) throw new Error(_('No item with title "%s" found.', title));
|
||||
|
||||
let newItem = {
|
||||
id: item.id,
|
||||
type_: item.type_,
|
||||
};
|
||||
newItem[propName] = propValue;
|
||||
let ItemClass = BaseItem.itemClass(newItem);
|
||||
await ItemClass.save(newItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ class Command extends BaseCommand {
|
||||
this.log(_('Starting synchronization...'));
|
||||
|
||||
await sync.start(options);
|
||||
vorpalUtils.redrawDone();
|
||||
this.log(_('Done.'));
|
||||
}
|
||||
}
|
||||
|
@ -17,19 +17,25 @@ class Command extends BaseCommand {
|
||||
async action(args) {
|
||||
let tag = null;
|
||||
if (args.tag) tag = await app().loadItem(BaseModel.TYPE_TAG, args.tag);
|
||||
let note = null;
|
||||
if (args.note) note = await app().loadItem(BaseModel.TYPE_NOTE, args.note);
|
||||
let notes = [];
|
||||
if (args.note) {
|
||||
notes = await app().loadItems(BaseModel.TYPE_NOTE, args.note);
|
||||
}
|
||||
|
||||
if (args.command == 'remove' && !tag) throw new Error(_('Tag does not exist: "%s"', args.tag));
|
||||
|
||||
if (args.command == 'add') {
|
||||
if (!note) throw new Error(_('Note does not exist: "%s"', args.note));
|
||||
if (!notes.length) throw new Error(_('Note does not exist: "%s"', args.note));
|
||||
if (!tag) tag = await Tag.save({ title: args.tag });
|
||||
await Tag.addNote(tag.id, note.id);
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Tag.addNote(tag.id, notes[i].id);
|
||||
}
|
||||
} else if (args.command == 'remove') {
|
||||
if (!tag) throw new Error(_('Tag does not exist: "%s"', args.tag));
|
||||
if (!note) throw new Error(_('Note does not exist: "%s"', args.note));
|
||||
await Tag.removeNote(tag.id, note.id);
|
||||
if (!notes.length) throw new Error(_('Note does not exist: "%s"', args.note));
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Tag.removeNote(tag.id, notes[i].id);
|
||||
}
|
||||
} else if (args.command == 'list') {
|
||||
if (tag) {
|
||||
let notes = await Tag.notes(tag.id);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { BaseCommand } from './base-command.js';
|
||||
import { app } from './app.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { BaseModel } from 'lib/base-model.js';
|
||||
import { Folder } from 'lib/models/folder.js';
|
||||
import { autocompleteFolders } from './autocomplete.js';
|
||||
|
||||
@ -23,10 +24,8 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let title = args['notebook'];
|
||||
|
||||
let folder = await Folder.loadByField('title', title);
|
||||
if (!folder) throw new Error(_('Invalid folder title: %s', title));
|
||||
let folder = await app().loadItem(BaseModel.TYPE_FOLDER, args['notebook']);
|
||||
if (!folder) throw new Error(_('No folder "%s"', title));
|
||||
app().switchCurrentFolder(folder);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ async function execRandomCommand(client) {
|
||||
if (item.type_ == 1) {
|
||||
return execCommand(client, 'rm -f ' + item.id);
|
||||
} else if (item.type_ == 2) {
|
||||
return execCommand(client, 'rm -f ' + '../' + item.id);
|
||||
return execCommand(client, 'rm -r -f ' + item.id);
|
||||
} else if (item.type_ == 5) {
|
||||
// tag
|
||||
} else {
|
||||
@ -153,7 +153,7 @@ async function execRandomCommand(client) {
|
||||
}, 30],
|
||||
[async () => { // UPDATE RANDOM ITEM
|
||||
let items = await clientItems(client);
|
||||
let item = randomElement(items);
|
||||
let item = randomNote(items);
|
||||
if (!item) return;
|
||||
|
||||
return execCommand(client, 'set ' + item.id + ' title "' + randomWord() + '"');
|
||||
|
@ -14,9 +14,9 @@ function initialize(vorpal) {
|
||||
}
|
||||
|
||||
function redrawEnabled() {
|
||||
// Always disabled for now - doesn't play well with command.cancel()
|
||||
// function (it makes the whole app quit instead of just the
|
||||
// current command).
|
||||
// // Always disabled for now - doesn't play well with command.cancel()
|
||||
// // function (it makes the whole app quit instead of just the
|
||||
// // current command).
|
||||
return false;
|
||||
|
||||
return redrawEnabled_;
|
||||
@ -33,7 +33,7 @@ function setStackTraceEnabled(v) {
|
||||
function redraw(s) {
|
||||
if (!redrawEnabled()) {
|
||||
const now = time.unixMs();
|
||||
if (now - redrawLastUpdateTime_ > 1000) {
|
||||
if (now - redrawLastUpdateTime_ > 4000) {
|
||||
if (vorpal_.activeCommand) {
|
||||
vorpal_.activeCommand.log(s);
|
||||
} else {
|
||||
|
@ -7,7 +7,7 @@
|
||||
"url": "https://github.com/laurent22/joplin"
|
||||
},
|
||||
"url": "git://github.com/laurent22/joplin.git",
|
||||
"version": "0.8.35",
|
||||
"version": "0.8.36",
|
||||
"bin": {
|
||||
"joplin": "./main_launcher.js"
|
||||
},
|
||||
|
@ -277,6 +277,12 @@ class BaseModel {
|
||||
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]);
|
||||
}
|
||||
|
||||
static batchDelete(ids, options = null) {
|
||||
options = this.modOptions(options);
|
||||
if (!ids.length) throw new Error('Cannot delete object without an ID');
|
||||
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id IN ("' + ids.join('","') + '")');
|
||||
}
|
||||
|
||||
static db() {
|
||||
if (!this.db_) throw new Error('Accessing database before it has been initialised');
|
||||
return this.db_;
|
||||
|
@ -133,13 +133,33 @@ class BaseItem extends BaseModel {
|
||||
}
|
||||
|
||||
static async delete(id, options = null) {
|
||||
return this.batchDelete([id], options);
|
||||
// let trackDeleted = true;
|
||||
// if (options && options.trackDeleted !== null && options.trackDeleted !== undefined) trackDeleted = options.trackDeleted;
|
||||
|
||||
// await super.delete(id, options);
|
||||
|
||||
// if (trackDeleted) {
|
||||
// await this.db().exec('INSERT INTO deleted_items (item_type, item_id, deleted_time) VALUES (?, ?, ?)', [this.modelType(), id, time.unixMs()]);
|
||||
// }
|
||||
}
|
||||
|
||||
static async batchDelete(ids, options = null) {
|
||||
let trackDeleted = true;
|
||||
if (options && options.trackDeleted !== null && options.trackDeleted !== undefined) trackDeleted = options.trackDeleted;
|
||||
|
||||
await super.delete(id, options);
|
||||
await super.batchDelete(ids, options);
|
||||
|
||||
if (trackDeleted) {
|
||||
await this.db().exec('INSERT INTO deleted_items (item_type, item_id, deleted_time) VALUES (?, ?, ?)', [this.modelType(), id, time.unixMs()]);
|
||||
let queries = [];
|
||||
let now = time.unixMs();
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
queries.push({
|
||||
sql: 'INSERT INTO deleted_items (item_type, item_id, deleted_time) VALUES (?, ?, ?)',
|
||||
params: [this.modelType(), ids[i], now],
|
||||
});
|
||||
}
|
||||
await this.db().transactionExecBatch(queries);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { Folder } from 'lib/models/folder.js';
|
||||
import { BaseItem } from 'lib/models/base-item.js';
|
||||
import { Setting } from 'lib/models/setting.js';
|
||||
import { shim } from 'lib/shim.js';
|
||||
import { time } from 'lib/time-utils.js';
|
||||
import moment from 'moment';
|
||||
import lodash from 'lodash';
|
||||
|
||||
@ -95,25 +96,41 @@ class Note extends BaseItem {
|
||||
return this.modelSelectAll('SELECT * FROM notes WHERE is_conflict = 0');
|
||||
}
|
||||
|
||||
static updateGeolocation(noteId) {
|
||||
static async updateGeolocation(noteId) {
|
||||
if (!Note.updateGeolocationEnabled_) return;
|
||||
|
||||
let startWait = time.unixMs();
|
||||
while (true) {
|
||||
if (!this.geolocationUpdating_) break;
|
||||
this.logger().info('Waiting for geolocation update...');
|
||||
await time.sleep(1);
|
||||
if (startWait + 1000 * 20 < time.unixMs()) {
|
||||
this.logger().warn('Failed to update geolocation for: timeout: ' + noteId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let geoData = null;
|
||||
if (this.geolocationCache_ && this.geolocationCache_.timestamp + 1000 * 60 * 10 > time.unixMs()) {
|
||||
geoData = Object.assign({}, this.geolocationCache_);
|
||||
} else {
|
||||
this.geolocationUpdating_ = true;
|
||||
this.logger().info('Fetching geolocation...');
|
||||
geoData = await shim.Geolocation.currentPosition();
|
||||
this.logger().info('Got lat/long');
|
||||
this.geolocationCache_ = geoData;
|
||||
this.geolocationUpdating_ = false;
|
||||
}
|
||||
|
||||
this.logger().info('Updating lat/long of note ' + noteId);
|
||||
|
||||
let geoData = null;
|
||||
return shim.Geolocation.currentPosition().then((data) => {
|
||||
this.logger().info('Got lat/long');
|
||||
geoData = data;
|
||||
return Note.load(noteId);
|
||||
}).then((note) => {
|
||||
if (!note) return; // Race condition - note has been deleted in the meantime
|
||||
note.longitude = geoData.coords.longitude;
|
||||
note.latitude = geoData.coords.latitude;
|
||||
note.altitude = geoData.coords.altitude;
|
||||
return Note.save(note);
|
||||
}).catch((error) => {
|
||||
this.logger().warn('Cannot get location:', error);
|
||||
});
|
||||
let note = Note.load(noteId);
|
||||
if (!note) return; // Race condition - note has been deleted in the meantime
|
||||
|
||||
note.longitude = geoData.coords.longitude;
|
||||
note.latitude = geoData.coords.latitude;
|
||||
note.altitude = geoData.coords.altitude;
|
||||
return Note.save(note);
|
||||
}
|
||||
|
||||
static filter(note) {
|
||||
@ -126,6 +143,24 @@ class Note extends BaseItem {
|
||||
return output;
|
||||
}
|
||||
|
||||
static async duplicate(noteId, options = null) {
|
||||
const changes = options && options.changes;
|
||||
|
||||
const originalNote = await Note.load(noteId);
|
||||
if (!originalNote) throw new Error('Unknown note: ' + noteId);
|
||||
|
||||
let newNote = Object.assign({}, originalNote);
|
||||
delete newNote.id;
|
||||
newNote.sync_time = 0;
|
||||
|
||||
for (let n in changes) {
|
||||
if (!changes.hasOwnProperty(n)) continue;
|
||||
newNote[n] = changes[n];
|
||||
}
|
||||
|
||||
return this.save(newNote);
|
||||
}
|
||||
|
||||
static save(o, options = null) {
|
||||
let isNew = this.isNew(o, options);
|
||||
if (isNew && !o.source) o.source = Setting.value('appName');
|
||||
@ -147,5 +182,6 @@ class Note extends BaseItem {
|
||||
}
|
||||
|
||||
Note.updateGeolocationEnabled_ = true;
|
||||
Note.geolocationUpdating_ = false;
|
||||
|
||||
export { Note };
|
Loading…
Reference in New Issue
Block a user