2023-07-11 14:48:03 +02:00
|
|
|
const axios = require("axios");
|
|
|
|
const readline = require("readline");
|
|
|
|
const fs = require("fs");
|
2023-08-24 17:19:03 +02:00
|
|
|
const openpgp = require("openpgp");
|
2023-07-11 14:48:03 +02:00
|
|
|
var cp = require("child_process");
|
|
|
|
|
|
|
|
var rl = readline.createInterface({
|
|
|
|
input: process.stdin,
|
|
|
|
output: process.stdout
|
|
|
|
});
|
|
|
|
|
|
|
|
var settings = JSON.parse(fs.readFileSync("settings.json", { encoding: "utf8", flag: "r" }));
|
2023-08-24 17:19:03 +02:00
|
|
|
var pgpkey = fs.readFileSync("key.acs", { encoding: "utf8", flag: "r" });
|
2023-07-11 18:09:04 +02:00
|
|
|
var filter = process.argv.length > 2 ? process.argv[2] : "";
|
2023-07-12 18:07:32 +02:00
|
|
|
var intervalid = null;
|
|
|
|
var notes = null;
|
|
|
|
|
2023-08-25 17:44:24 +02:00
|
|
|
function simplifystring(str)
|
|
|
|
{
|
|
|
|
return str.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, "");
|
|
|
|
}
|
|
|
|
|
2023-08-24 17:19:03 +02:00
|
|
|
async function decrypt(str)
|
|
|
|
{
|
|
|
|
var key = pgpkey.split("-----END PGP PUBLIC KEY BLOCK-----")[1];
|
|
|
|
var privateKey = await openpgp.readKey({ armoredKey: key });
|
|
|
|
var decrypted = await openpgp.decrypt({
|
|
|
|
message: await openpgp.readMessage({ armoredMessage: str }),
|
|
|
|
decryptionKeys: privateKey });
|
|
|
|
const chunks = [];
|
|
|
|
for await (const chunk of decrypted.data) {
|
|
|
|
chunks.push(chunk);
|
|
|
|
}
|
|
|
|
return chunks.join('');
|
|
|
|
}
|
|
|
|
|
|
|
|
async function encrypt(str)
|
|
|
|
{
|
|
|
|
var key = pgpkey.split("-----BEGIN PGP PRIVATE KEY BLOCK-----")[0];
|
|
|
|
var publicKey = await openpgp.readKey({ armoredKey: key });
|
|
|
|
return await openpgp.encrypt({
|
|
|
|
message: await openpgp.createMessage({ text: str }),
|
|
|
|
encryptionKeys: publicKey });
|
|
|
|
}
|
|
|
|
|
2023-07-12 18:07:32 +02:00
|
|
|
function filteredlist()
|
|
|
|
{
|
|
|
|
return notes
|
2023-08-25 17:44:24 +02:00
|
|
|
.filter(n => simplifystring(n.title).includes(simplifystring(filter)));
|
2023-07-12 18:07:32 +02:00
|
|
|
}
|
2023-07-11 14:48:03 +02:00
|
|
|
|
|
|
|
axios.post(`${settings.url}/handler.php`,
|
|
|
|
{
|
|
|
|
action: "fetch",
|
|
|
|
password: settings.password
|
|
|
|
},
|
|
|
|
{
|
|
|
|
headers:
|
|
|
|
{
|
|
|
|
"Content-type": "application/x-www-form-urlencoded"
|
|
|
|
}
|
|
|
|
})
|
2023-08-24 17:19:03 +02:00
|
|
|
.then(async function(res)
|
2023-07-11 14:48:03 +02:00
|
|
|
{
|
2023-08-24 17:19:03 +02:00
|
|
|
notes = JSON.parse(await decrypt(res.data));
|
2023-07-11 18:09:04 +02:00
|
|
|
|
2023-07-12 18:07:32 +02:00
|
|
|
filteredlist()
|
2023-07-11 18:09:04 +02:00
|
|
|
.every( (note, i) =>
|
2023-07-11 14:48:03 +02:00
|
|
|
{
|
|
|
|
console.log(`[${i}] ${note.title}`)
|
2023-08-25 17:57:20 +02:00
|
|
|
return Boolean(filter) || i < settings.maxcountifnofilter;
|
2023-07-11 14:48:03 +02:00
|
|
|
});
|
|
|
|
|
2023-07-12 18:07:32 +02:00
|
|
|
// todo: open if only one match. quit if no match
|
2023-07-11 14:48:03 +02:00
|
|
|
rl.prompt();
|
2023-08-24 17:19:03 +02:00
|
|
|
rl.on("line", async function (line)
|
2023-07-11 14:48:03 +02:00
|
|
|
{
|
2023-07-12 18:07:32 +02:00
|
|
|
var note = filteredlist()[line];
|
2023-07-11 14:48:03 +02:00
|
|
|
|
2023-07-12 18:07:32 +02:00
|
|
|
// todo: use title instead? To put in data folder?
|
2023-07-11 14:48:03 +02:00
|
|
|
fs.writeFileSync("note.md", note.content);
|
|
|
|
|
2023-08-24 17:19:03 +02:00
|
|
|
cp.exec(`${settings.command} note.md`, async function (err, stdout, stderr)
|
2023-07-11 14:48:03 +02:00
|
|
|
{
|
2023-07-12 18:07:32 +02:00
|
|
|
clearInterval(intervalid);
|
2023-07-11 14:48:03 +02:00
|
|
|
var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" });
|
|
|
|
if (note.content != newcontent)
|
|
|
|
{
|
|
|
|
note.content = newcontent;
|
2023-07-11 18:09:04 +02:00
|
|
|
|
|
|
|
notes.splice(notes.indexOf(note), 1);
|
|
|
|
notes.unshift(note);
|
|
|
|
|
2023-07-11 18:16:51 +02:00
|
|
|
console.log("sending data file to server...");
|
2023-08-24 17:19:03 +02:00
|
|
|
var encrypted = await encrypt(JSON.stringify(notes));
|
2023-07-11 14:48:03 +02:00
|
|
|
axios.post(`${settings.url}/handler.php`,
|
|
|
|
{
|
|
|
|
action: "push",
|
|
|
|
password: settings.password,
|
2023-08-24 17:19:03 +02:00
|
|
|
data: encrypted
|
2023-07-11 14:48:03 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
headers:
|
|
|
|
{
|
|
|
|
"Content-type": "application/x-www-form-urlencoded"
|
|
|
|
}
|
2023-07-11 18:16:51 +02:00
|
|
|
}).then(res => {
|
|
|
|
console.log("done.");
|
2023-07-11 14:48:03 +02:00
|
|
|
});
|
|
|
|
}
|
2023-07-11 18:16:51 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
console.log("no change.");
|
|
|
|
}
|
2023-07-11 14:48:03 +02:00
|
|
|
})
|
2023-07-12 18:07:32 +02:00
|
|
|
|
2023-08-24 17:19:03 +02:00
|
|
|
intervalid = setInterval(async function()
|
2023-07-12 18:07:32 +02:00
|
|
|
{
|
|
|
|
//todo: refactor "save"
|
|
|
|
var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" });
|
|
|
|
if (note.content != newcontent)
|
|
|
|
{
|
|
|
|
note.content = newcontent;
|
|
|
|
|
|
|
|
notes.splice(notes.indexOf(note), 1);
|
|
|
|
notes.unshift(note);
|
|
|
|
|
|
|
|
console.log("sending data file to server...");
|
2023-08-24 17:19:03 +02:00
|
|
|
var encrypted = await encrypt(JSON.stringify(notes));
|
2023-07-12 18:07:32 +02:00
|
|
|
axios.post(`${settings.url}/handler.php`,
|
|
|
|
{
|
|
|
|
action: "push",
|
|
|
|
password: settings.password,
|
2023-08-24 17:19:03 +02:00
|
|
|
data: encrypted
|
2023-07-12 18:07:32 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
headers:
|
|
|
|
{
|
|
|
|
"Content-type": "application/x-www-form-urlencoded"
|
|
|
|
}
|
|
|
|
}).then(res => {
|
|
|
|
console.log("done.");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}, 10000);
|
|
|
|
|
2023-07-11 14:48:03 +02:00
|
|
|
rl.close();
|
|
|
|
});
|
|
|
|
});
|