mirror of
https://github.com/zadam/trilium.git
synced 2025-10-27 08:16:40 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69cbfaae17 | ||
|
|
aebce8f12b | ||
|
|
045ca1f0bf | ||
|
|
bf2db6eac7 | ||
|
|
cf84114f91 | ||
|
|
6426157bb3 | ||
|
|
332fc16852 | ||
|
|
da2cd57428 | ||
|
|
de9bab1181 | ||
|
|
136375cf11 | ||
|
|
eabc7f80b7 | ||
|
|
6405d6e066 | ||
|
|
f6d481a9e2 | ||
|
|
695f0e5879 | ||
|
|
ae337e4500 | ||
|
|
19ffa14f10 | ||
|
|
bf3f26fde8 |
10
bin/build.sh
10
bin/build.sh
@@ -8,9 +8,15 @@ cp -r ../trilium-node-binaries/sqlite/* node_modules/sqlite3/lib/binding/
|
|||||||
|
|
||||||
cp -r ../trilium-node-binaries/scrypt/* node_modules/scrypt/bin/
|
cp -r ../trilium-node-binaries/scrypt/* node_modules/scrypt/bin/
|
||||||
|
|
||||||
./node_modules/.bin/electron-rebuild
|
./node_modules/.bin/electron-rebuild --arch=ia32
|
||||||
|
|
||||||
./node_modules/.bin/electron-packager . --out=dist --platform=linux,win32 --overwrite
|
./node_modules/.bin/electron-packager . --out=dist --platform=linux --arch=ia32 --overwrite
|
||||||
|
|
||||||
|
./node_modules/.bin/electron-rebuild --arch=x64
|
||||||
|
|
||||||
|
./node_modules/.bin/electron-packager . --out=dist --platform=linux --arch=x64 --overwrite
|
||||||
|
|
||||||
|
./node_modules/.bin/electron-packager . --out=dist --platform=win32 --arch=x64 --overwrite
|
||||||
|
|
||||||
# can't copy this before the packaging because the same file name is used for both linux and windows build
|
# can't copy this before the packaging because the same file name is used for both linux and windows build
|
||||||
cp ../trilium-node-binaries/scrypt.node ./dist/trilium-win32-x64/resources/app/node_modules/scrypt/build/Release/
|
cp ../trilium-node-binaries/scrypt.node ./dist/trilium-win32-x64/resources/app/node_modules/scrypt/build/Release/
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ VERSION=`jq -r ".version" package.json`
|
|||||||
|
|
||||||
cd dist
|
cd dist
|
||||||
|
|
||||||
echo "Packaging windows electron distribution..."
|
echo "Packaging linux x64 electron distribution..."
|
||||||
7z a trilium-windows-${VERSION}.7z trilium-win32-x64
|
7z a trilium-linux-x64-${VERSION}.7z trilium-linux-x64
|
||||||
|
|
||||||
echo "Packaging linux electron distribution..."
|
echo "Packaging linux ia32 electron distribution..."
|
||||||
7z a trilium-linux-${VERSION}.7z trilium-linux-x64
|
7z a trilium-linux-ia32-${VERSION}.7z trilium-linux-ia32
|
||||||
|
|
||||||
|
echo "Packaging windows x64 electron distribution..."
|
||||||
|
7z a trilium-windows-x64-${VERSION}.7z trilium-win32-x64
|
||||||
@@ -44,8 +44,9 @@ bin/build.sh
|
|||||||
|
|
||||||
bin/package.sh
|
bin/package.sh
|
||||||
|
|
||||||
LINUX_BUILD=trilium-linux-$VERSION.7z
|
LINUX_X64_BUILD=trilium-linux-x64-$VERSION.7z
|
||||||
WINDOWS_BUILD=trilium-windows-$VERSION.7z
|
LINUX_IA32_BUILD=trilium-linux-ia32-$VERSION.7z
|
||||||
|
WINDOWS_X64_BUILD=trilium-windows-x64-$VERSION.7z
|
||||||
|
|
||||||
echo "Creating release in GitHub"
|
echo "Creating release in GitHub"
|
||||||
|
|
||||||
@@ -53,18 +54,25 @@ github-release release \
|
|||||||
--tag $TAG \
|
--tag $TAG \
|
||||||
--name "$TAG release"
|
--name "$TAG release"
|
||||||
|
|
||||||
echo "Uploading linux build"
|
echo "Uploading linux x64 build"
|
||||||
|
|
||||||
github-release upload \
|
github-release upload \
|
||||||
--tag $TAG \
|
--tag $TAG \
|
||||||
--name "$LINUX_BUILD" \
|
--name "$LINUX_X64_BUILD" \
|
||||||
--file "dist/$LINUX_BUILD"
|
--file "dist/$LINUX_X64_BUILD"
|
||||||
|
|
||||||
echo "Uploading windows build"
|
echo "Uploading linux ia32 build"
|
||||||
|
|
||||||
github-release upload \
|
github-release upload \
|
||||||
--tag $TAG \
|
--tag $TAG \
|
||||||
--name "$WINDOWS_BUILD" \
|
--name "$LINUX_IA32_BUILD" \
|
||||||
--file "dist/$WINDOWS_BUILD"
|
--file "dist/$LINUX_IA32_BUILD"
|
||||||
|
|
||||||
|
echo "Uploading windows x64 build"
|
||||||
|
|
||||||
|
github-release upload \
|
||||||
|
--tag $TAG \
|
||||||
|
--name "$WINDOWS_X64_BUILD" \
|
||||||
|
--file "dist/$WINDOWS_X64_BUILD"
|
||||||
|
|
||||||
echo "Release finished!"
|
echo "Release finished!"
|
||||||
1
index.js
1
index.js
@@ -21,6 +21,7 @@ function createMainWindow() {
|
|||||||
const win = new electron.BrowserWindow({
|
const win = new electron.BrowserWindow({
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 900,
|
height: 900,
|
||||||
|
title: 'Trilium Notes',
|
||||||
icon: path.join(__dirname, 'public/images/app-icons/png/256x256.png')
|
icon: path.join(__dirname, 'public/images/app-icons/png/256x256.png')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.0.11",
|
"version": "0.1.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./bin/www",
|
"start": "node ./bin/www",
|
||||||
"test-electron": "xo",
|
"test-electron": "xo",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ const noteSource = (function() {
|
|||||||
|
|
||||||
dialogEl.dialog({
|
dialogEl.dialog({
|
||||||
modal: true,
|
modal: true,
|
||||||
width: 800
|
width: 800,
|
||||||
|
height: 500
|
||||||
});
|
});
|
||||||
|
|
||||||
const noteText = noteEditor.getCurrentNote().detail.note_text;
|
const noteText = noteEditor.getCurrentNote().detail.note_text;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ $(document).bind('keydown', 'ctrl+f', () => {
|
|||||||
const searchInPage = require('electron-in-page-search').default;
|
const searchInPage = require('electron-in-page-search').default;
|
||||||
const remote = require('electron').remote;
|
const remote = require('electron').remote;
|
||||||
|
|
||||||
const inPageSearch = searchInPage(remote.getCurrentWebContents(), { openDevToolsOfSearchWindow: true });
|
const inPageSearch = searchInPage(remote.getCurrentWebContents());
|
||||||
|
|
||||||
inPageSearch.openSearchWindow();
|
inPageSearch.openSearchWindow();
|
||||||
|
|
||||||
@@ -57,6 +57,42 @@ $(document).bind('keydown', 'ctrl+f', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+left", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.LEFT, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+right", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.RIGHT, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+up", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.UP, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+down", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.DOWN, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
$(window).on('beforeunload', () => {
|
$(window).on('beforeunload', () => {
|
||||||
// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved
|
// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved
|
||||||
// this sends the request asynchronously and doesn't wait for result
|
// this sends the request asynchronously and doesn't wait for result
|
||||||
@@ -164,4 +200,6 @@ window.onerror = function (msg, url, lineNo, columnNo, error) {
|
|||||||
messaging.logError(message);
|
messaging.logError(message);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$("#logout-button").toggle(!isElectron());
|
||||||
@@ -128,6 +128,9 @@ const noteEditor = (function() {
|
|||||||
setNoteBackgroundIfProtected(currentNote);
|
setNoteBackgroundIfProtected(currentNote);
|
||||||
noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId);
|
noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId);
|
||||||
|
|
||||||
|
// after loading new note make sure editor is scrolled to the top
|
||||||
|
noteDetailWrapperEl.scrollTop(0);
|
||||||
|
|
||||||
showAppIfHidden();
|
showAppIfHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const noteTree = (function() {
|
|||||||
const treeEl = $("#tree");
|
const treeEl = $("#tree");
|
||||||
const parentListEl = $("#parent-list");
|
const parentListEl = $("#parent-list");
|
||||||
const parentListListEl = $("#parent-list-list");
|
const parentListListEl = $("#parent-list-list");
|
||||||
|
const noteDetailEl = $("#note-detail");
|
||||||
|
|
||||||
let startNotePath = null;
|
let startNotePath = null;
|
||||||
let notesTreeMap = {};
|
let notesTreeMap = {};
|
||||||
@@ -59,23 +60,6 @@ const noteTree = (function() {
|
|||||||
return treeUtils.getNotePath(node);
|
return treeUtils.getNotePath(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentNoteId() {
|
|
||||||
const node = getCurrentNode();
|
|
||||||
|
|
||||||
return node ? node.data.note_id : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentClones() {
|
|
||||||
const noteId = getCurrentNoteId();
|
|
||||||
|
|
||||||
if (noteId) {
|
|
||||||
return getNodesByNoteId(noteId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodesByNoteTreeId(noteTreeId) {
|
function getNodesByNoteTreeId(noteTreeId) {
|
||||||
assertArguments(noteTreeId);
|
assertArguments(noteTreeId);
|
||||||
|
|
||||||
@@ -185,13 +169,15 @@ const noteTree = (function() {
|
|||||||
const noteTreeId = getNoteTreeId(parentNoteId, noteId);
|
const noteTreeId = getNoteTreeId(parentNoteId, noteId);
|
||||||
const noteTree = notesTreeMap[noteTreeId];
|
const noteTree = notesTreeMap[noteTreeId];
|
||||||
|
|
||||||
|
const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id];
|
||||||
|
|
||||||
const node = {
|
const node = {
|
||||||
note_id: noteTree.note_id,
|
note_id: noteTree.note_id,
|
||||||
parent_note_id: noteTree.parent_note_id,
|
parent_note_id: noteTree.parent_note_id,
|
||||||
note_tree_id: noteTree.note_tree_id,
|
note_tree_id: noteTree.note_tree_id,
|
||||||
is_protected: noteTree.is_protected,
|
is_protected: noteTree.is_protected,
|
||||||
prefix: noteTree.prefix,
|
prefix: noteTree.prefix,
|
||||||
title: (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id],
|
title: escapeHtml(title),
|
||||||
extraClasses: getExtraClasses(noteTree),
|
extraClasses: getExtraClasses(noteTree),
|
||||||
refKey: noteTree.note_id,
|
refKey: noteTree.note_id,
|
||||||
expanded: noteTree.is_expanded
|
expanded: noteTree.is_expanded
|
||||||
@@ -432,6 +418,30 @@ const noteTree = (function() {
|
|||||||
"alt+-": node => {
|
"alt+-": node => {
|
||||||
collapseTree(node);
|
collapseTree(node);
|
||||||
},
|
},
|
||||||
|
"ctrl+c": node => {
|
||||||
|
contextMenu.copy(node);
|
||||||
|
|
||||||
|
showMessage("Note copied into clipboard.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"ctrl+x": node => {
|
||||||
|
contextMenu.cut(node);
|
||||||
|
|
||||||
|
showMessage("Note cut into clipboard.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"ctrl+v": node => {
|
||||||
|
contextMenu.pasteInto(node);
|
||||||
|
|
||||||
|
showMessage("Note pasted from clipboard into current note.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"ctrl+return": node => {
|
||||||
|
noteDetailEl.focus();
|
||||||
|
},
|
||||||
// code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin
|
// code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin
|
||||||
// after opening context menu, standard shortcuts don't work, but they are detected here
|
// after opening context menu, standard shortcuts don't work, but they are detected here
|
||||||
// so we essentially takeover the standard handling with our implementation.
|
// so we essentially takeover the standard handling with our implementation.
|
||||||
@@ -513,57 +523,6 @@ const noteTree = (function() {
|
|||||||
mode: "hide" // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
|
mode: "hide" // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
|
||||||
},
|
},
|
||||||
dnd: dragAndDropSetup,
|
dnd: dragAndDropSetup,
|
||||||
keydown: (event, data) => {
|
|
||||||
const node = data.node;
|
|
||||||
// Eat keyboard events, when a menu is open
|
|
||||||
if ($(".contextMenu:visible").length > 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (event.which) {
|
|
||||||
// Open context menu on [Space] key (simulate right click)
|
|
||||||
case 32: // [Space]
|
|
||||||
$(node.span).trigger("mousedown", {
|
|
||||||
preventDefault: true,
|
|
||||||
button: 2
|
|
||||||
})
|
|
||||||
.trigger("mouseup", {
|
|
||||||
preventDefault: true,
|
|
||||||
pageX: node.span.offsetLeft,
|
|
||||||
pageY: node.span.offsetTop,
|
|
||||||
button: 2
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Handle Ctrl+C, +X and +V
|
|
||||||
case 67:
|
|
||||||
if (event.ctrlKey) { // Ctrl+C
|
|
||||||
contextMenu.copy(node);
|
|
||||||
|
|
||||||
showMessage("Note copied into clipboard.");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 88:
|
|
||||||
if (event.ctrlKey) { // Ctrl+X
|
|
||||||
contextMenu.cut(node);
|
|
||||||
|
|
||||||
showMessage("Note cut into clipboard.");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 86:
|
|
||||||
if (event.ctrlKey) { // Ctrl+V
|
|
||||||
contextMenu.pasteInto(node);
|
|
||||||
|
|
||||||
showMessage("Note pasted from clipboard into current note.");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lazyLoad: function(event, data){
|
lazyLoad: function(event, data){
|
||||||
const node = data.node.data;
|
const node = data.node.data;
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,12 @@ const treeChanges = (function() {
|
|||||||
await server.put('notes/' + node.data.note_tree_id + '/move-to/' + toNode.data.note_id);
|
await server.put('notes/' + node.data.note_tree_id + '/move-to/' + toNode.data.note_id);
|
||||||
|
|
||||||
changeNode(node, node => {
|
changeNode(node, node => {
|
||||||
node.moveTo(toNode);
|
// first expand which will force lazy load and only then move the node
|
||||||
|
// if this is not expanded before moving, then lazy load won't happen because it already contains node
|
||||||
toNode.setExpanded(true);
|
toNode.setExpanded(true);
|
||||||
|
|
||||||
|
node.moveTo(toNode);
|
||||||
|
|
||||||
toNode.folder = true;
|
toNode.folder = true;
|
||||||
toNode.renderTitle();
|
toNode.renderTitle();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const treeUtils = (function() {
|
|||||||
|
|
||||||
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
|
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
|
||||||
|
|
||||||
node.setTitle(title);
|
node.setTitle(escapeHtml(title));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -93,4 +93,8 @@ function isTopLevelNode(node) {
|
|||||||
|
|
||||||
function isRootNode(node) {
|
function isRootNode(node) {
|
||||||
return node.key === "root_1";
|
return node.key === "root_1";
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(str) {
|
||||||
|
return $('<div/>').text(str).html();
|
||||||
}
|
}
|
||||||
@@ -74,6 +74,12 @@ span.fancytree-node.fancytree-active-clone:not(.fancytree-active) .fancytree-tit
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* By default not focused active tree item is not easily visible, this makes it more visible */
|
||||||
|
span.fancytree-active:not(.fancytree-focused) .fancytree-title {
|
||||||
|
background-color: #ddd !important;
|
||||||
|
border-color: #555 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ui-autocomplete {
|
.ui-autocomplete {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -185,6 +191,12 @@ div.ui-tooltip {
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#note-source {
|
||||||
|
height: 98%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
#loader-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1000;background-color:#fff;opacity:1;transition:opacity 2s ease}
|
#loader-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1000;background-color:#fff;opacity:1;transition:opacity 2s ease}
|
||||||
#loader{display:block;position:relative;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50%;border:3px solid transparent;border-top-color:#777;-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}
|
#loader{display:block;position:relative;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50%;border:3px solid transparent;border-top-color:#777;-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}
|
||||||
#loader:before{content:"";position:absolute;top:5px;left:5px;right:5px;bottom:5px;border-radius:50%;border:3px solid transparent;border-top-color:#aaa;-webkit-animation:spin 3s linear infinite;animation:spin 3s linear infinite}
|
#loader:before{content:"";position:absolute;top:5px;left:5px;right:5px;bottom:5px;border-radius:50%;border:3px solid transparent;border-top-color:#aaa;-webkit-animation:spin 3s linear infinite;animation:spin 3s linear infinite}
|
||||||
|
|||||||
@@ -3,12 +3,9 @@
|
|||||||
const migration = require('./migration');
|
const migration = require('./migration');
|
||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
const options = require('./options');
|
|
||||||
|
|
||||||
async function checkAuth(req, res, next) {
|
async function checkAuth(req, res, next) {
|
||||||
const username = await options.getOption('username');
|
if (!await sql.isUserInitialized()) {
|
||||||
|
|
||||||
if (!username) {
|
|
||||||
res.redirect("setup");
|
res.redirect("setup");
|
||||||
}
|
}
|
||||||
else if (!req.session.loggedIn && !utils.isElectron()) {
|
else if (!req.session.loggedIn && !utils.isElectron()) {
|
||||||
@@ -53,9 +50,7 @@ async function checkApiAuthForMigrationPage(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function checkAppNotInitialized(req, res, next) {
|
async function checkAppNotInitialized(req, res, next) {
|
||||||
const username = await options.getOption('username');
|
if (await sql.isUserInitialized()) {
|
||||||
|
|
||||||
if (username) {
|
|
||||||
res.status(400).send("App already initialized.");
|
res.status(400).send("App already initialized.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module.exports = { build_date:"2017-12-26T19:57:44-05:00", build_revision: "baab7454626b154b43144c1a07e1962ab083bde2" };
|
module.exports = { build_date:"2017-12-28T21:17:25-05:00", build_revision: "aebce8f12b87e7c3d5dbd23e75918f3d01a4cc64" };
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ const ini = require('ini');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const dataDir = require('./data_dir');
|
const dataDir = require('./data_dir');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const resource_dir = require('./resource_dir');
|
||||||
|
|
||||||
const configSampleFilePath = path.resolve(__dirname, "..", "config-sample.ini");
|
const configSampleFilePath = path.resolve(resource_dir.RESOURCE_DIR, "config-sample.ini");
|
||||||
|
|
||||||
const configFilePath = dataDir.TRILIUM_DATA_DIR + '/config.ini';
|
const configFilePath = dataDir.TRILIUM_DATA_DIR + '/config.ini';
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,7 @@ const sql = require('./sql');
|
|||||||
const options = require('./options');
|
const options = require('./options');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const log = require('./log');
|
const log = require('./log');
|
||||||
const path = require('path');
|
const resource_dir = require('./resource_dir');
|
||||||
|
|
||||||
const MIGRATIONS_DIR = path.resolve(__dirname, "..", "migrations");
|
|
||||||
|
|
||||||
if (!fs.existsSync(MIGRATIONS_DIR)) {
|
|
||||||
log.error("Could not find migration directory: " + MIGRATIONS_DIR);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
const migrations = [];
|
const migrations = [];
|
||||||
@@ -20,7 +13,7 @@ async function migrate() {
|
|||||||
|
|
||||||
const currentDbVersion = parseInt(await options.getOption('db_version'));
|
const currentDbVersion = parseInt(await options.getOption('db_version'));
|
||||||
|
|
||||||
fs.readdirSync(MIGRATIONS_DIR).forEach(file => {
|
fs.readdirSync(resource_dir.MIGRATIONS_DIR).forEach(file => {
|
||||||
const match = file.match(/([0-9]{4})__([a-zA-Z0-9_ ]+)\.(sql|js)/);
|
const match = file.match(/([0-9]{4})__([a-zA-Z0-9_ ]+)\.(sql|js)/);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
@@ -53,7 +46,7 @@ async function migrate() {
|
|||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await sql.doInTransaction(async () => {
|
||||||
if (mig.type === 'sql') {
|
if (mig.type === 'sql') {
|
||||||
const migrationSql = fs.readFileSync(MIGRATIONS_DIR + "/" + mig.file).toString('utf8');
|
const migrationSql = fs.readFileSync(resource_dir.MIGRATIONS_DIR + "/" + mig.file).toString('utf8');
|
||||||
|
|
||||||
console.log("Migration with SQL script: " + migrationSql);
|
console.log("Migration with SQL script: " + migrationSql);
|
||||||
|
|
||||||
@@ -62,7 +55,7 @@ async function migrate() {
|
|||||||
else if (mig.type === 'js') {
|
else if (mig.type === 'js') {
|
||||||
console.log("Migration with JS module");
|
console.log("Migration with JS module");
|
||||||
|
|
||||||
const migrationModule = require("../" + MIGRATIONS_DIR + "/" + mig.file);
|
const migrationModule = require("../" + resource_dir.MIGRATIONS_DIR + "/" + mig.file);
|
||||||
await migrationModule(db);
|
await migrationModule(db);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
25
services/resource_dir.js
Normal file
25
services/resource_dir.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
const log = require('./log');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const RESOURCE_DIR = path.resolve(__dirname, "..");
|
||||||
|
|
||||||
|
const MIGRATIONS_DIR = path.resolve(RESOURCE_DIR, "migrations");
|
||||||
|
|
||||||
|
if (!fs.existsSync(MIGRATIONS_DIR)) {
|
||||||
|
log.error("Could not find migration directory: " + MIGRATIONS_DIR);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DB_INIT_DIR = path.resolve(RESOURCE_DIR, "db");
|
||||||
|
|
||||||
|
if (!fs.existsSync(DB_INIT_DIR)) {
|
||||||
|
log.error("Could not find DB initialization directory: " + DB_INIT_DIR);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
RESOURCE_DIR,
|
||||||
|
MIGRATIONS_DIR,
|
||||||
|
DB_INIT_DIR
|
||||||
|
};
|
||||||
@@ -4,8 +4,8 @@ const log = require('./log');
|
|||||||
const dataDir = require('./data_dir');
|
const dataDir = require('./data_dir');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const sqlite = require('sqlite');
|
const sqlite = require('sqlite');
|
||||||
const utils = require('./utils');
|
|
||||||
const app_info = require('./app_info');
|
const app_info = require('./app_info');
|
||||||
|
const resource_dir = require('./resource_dir');
|
||||||
|
|
||||||
async function createConnection() {
|
async function createConnection() {
|
||||||
return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise});
|
return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise});
|
||||||
@@ -28,9 +28,9 @@ const dbReady = new Promise((resolve, reject) => {
|
|||||||
if (tableResults.length !== 1) {
|
if (tableResults.length !== 1) {
|
||||||
log.info("Connected to db, but schema doesn't exist. Initializing schema ...");
|
log.info("Connected to db, but schema doesn't exist. Initializing schema ...");
|
||||||
|
|
||||||
const schema = fs.readFileSync('db/schema.sql', 'UTF-8');
|
const schema = fs.readFileSync(resource_dir.DB_INIT_DIR + '/schema.sql', 'UTF-8');
|
||||||
const notesSql = fs.readFileSync('db/main_notes.sql', 'UTF-8');
|
const notesSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_notes.sql', 'UTF-8');
|
||||||
const notesTreeSql = fs.readFileSync('db/main_notes_tree.sql', 'UTF-8');
|
const notesTreeSql = fs.readFileSync(resource_dir.DB_INIT_DIR + '/main_notes_tree.sql', 'UTF-8');
|
||||||
|
|
||||||
await doInTransaction(async () => {
|
await doInTransaction(async () => {
|
||||||
await executeScript(schema);
|
await executeScript(schema);
|
||||||
@@ -49,9 +49,7 @@ const dbReady = new Promise((resolve, reject) => {
|
|||||||
// the database
|
// the database
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
|
if (!await isUserInitialized()) {
|
||||||
|
|
||||||
if (!username) {
|
|
||||||
log.info("Login/password not initialized. DB not ready.");
|
log.info("Login/password not initialized. DB not ready.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -235,8 +233,15 @@ async function isDbUpToDate() {
|
|||||||
return upToDate;
|
return upToDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function isUserInitialized() {
|
||||||
|
const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
|
||||||
|
|
||||||
|
return !!username;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dbReady,
|
dbReady,
|
||||||
|
isUserInitialized,
|
||||||
insert,
|
insert,
|
||||||
replace,
|
replace,
|
||||||
getFirstValue,
|
getFirstValue,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<button class="btn btn-xs" onclick="settings.showDialog();">Settings</button>
|
<button class="btn btn-xs" onclick="settings.showDialog();">Settings</button>
|
||||||
|
|
||||||
<form action="logout" method="POST" style="display: inline;">
|
<form action="logout" id="logout-button" method="POST" style="display: inline;">
|
||||||
<input type="submit" class="btn btn-xs" value="Logout">
|
<input type="submit" class="btn btn-xs" value="Logout">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -172,11 +172,11 @@
|
|||||||
<div id="protected-session-password-dialog" title="Protected session" style="display: none;">
|
<div id="protected-session-password-dialog" title="Protected session" style="display: none;">
|
||||||
<form id="protected-session-password-form">
|
<form id="protected-session-password-form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="protected-session-password">To proceed with requested action you need to enter protected session by entering password:</label>
|
<label for="protected-session-password">To proceed with requested action you need to start protected session by entering password:</label>
|
||||||
<input id="protected-session-password" class="form-control" type="password">
|
<input id="protected-session-password" class="form-control" type="password">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-sm">Enter protected session <kbd>enter</kbd></button>
|
<button class="btn btn-sm">Start protected session <kbd>enter</kbd></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="note-source-dialog" title="Note source" style="display: none; padding: 20px;">
|
<div id="note-source-dialog" title="Note source" style="display: none; padding: 20px;">
|
||||||
<pre id="note-source"></pre>
|
<textarea id="note-source" readonly="readonly"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="tooltip" style="display: none;"></div>
|
<div id="tooltip" style="display: none;"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user