Initialize project
This commit is contained in:
parent
259b78b73a
commit
1e92cd541d
5 changed files with 299 additions and 1 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "brainlet-lib"]
|
||||||
|
path = brainlet-lib
|
||||||
|
url = https://git.hippoz.xyz/hiimgoodpack/brainlet-lib.git
|
17
README.md
17
README.md
|
@ -1,3 +1,18 @@
|
||||||
# brainlet-cli
|
# brainlet-cli
|
||||||
|
|
||||||
a better frontend for brainlet
|
a better (unofficial) frontend for brainlet
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
```
|
||||||
|
git clone --depth=1 --recurse-submodules https://git.hippoz.xyz/hiimgoodpack/brainlet-cli.git
|
||||||
|
cd brainlet-cli
|
||||||
|
pushd brainlet-lib
|
||||||
|
npm install
|
||||||
|
popd
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
```
|
||||||
|
node index.js <server>
|
||||||
|
```
|
||||||
|
|
1
brainlet-lib
Submodule
1
brainlet-lib
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit b3d9f220b0941c088060c867135ff804d10fad77
|
261
index.js
Normal file
261
index.js
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
Unofficial brainlet command-line interface
|
||||||
|
Copyright (C) 2020 hiimgoodpack
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const brainlet = require("./brainlet-lib/index.js");
|
||||||
|
const readline = require("readline").createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
|
||||||
|
const ask = (question) => {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
readline.question(question, res);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const catchErrors = (promise) => {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
promise.then(res).catch((...errors) => {
|
||||||
|
console.error(...errors);
|
||||||
|
res(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const promiseSucceeded = async (promise) => {
|
||||||
|
return await new Promise((res, rej) => {
|
||||||
|
promise.then(() => {
|
||||||
|
res(true);
|
||||||
|
}).catch((...errors) => {
|
||||||
|
console.error(...errors);
|
||||||
|
res(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getColorCode = ([r, g, b]) => {
|
||||||
|
return `\x1b[38;2;${r};${g};${b}m`;
|
||||||
|
};
|
||||||
|
const resetColorCode = "\x1b[0m";
|
||||||
|
const clearLine = "\x1b[2K";
|
||||||
|
|
||||||
|
const hexToRGB = (hex) => {
|
||||||
|
let decimal = parseInt(hex.substr(1), 16);
|
||||||
|
return [(decimal & 0xFF0000) >> 16, (decimal & 0xFF00) >> 8, decimal & 0xFF];
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = {};
|
||||||
|
|
||||||
|
console.log(`Unofficial brainlet command-line interface
|
||||||
|
Copyright (C) 2020 hiimgoodpack
|
||||||
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||||
|
|
||||||
|
Warning: You should not connect to an untrusted server,
|
||||||
|
or a server with untrusted clients, as there may be some risks
|
||||||
|
with outputting arbritrary text ot the console.
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Put in async function
|
||||||
|
(async() => {
|
||||||
|
const server = process.argv[2];
|
||||||
|
let prompt = 1;
|
||||||
|
let developerMode = 0;
|
||||||
|
let socket;
|
||||||
|
|
||||||
|
const useDeveloperMode = () => {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
if (!developerMode) {
|
||||||
|
ask(`Warning: This command requires developer mode to be enabled.
|
||||||
|
Enabling developer mode may enable commands which can reveal private information or information
|
||||||
|
which can be used to log into your account.
|
||||||
|
|
||||||
|
Note: Every time the client is started, developer mode is disabled, even if you have enabled it previously in another session.
|
||||||
|
|
||||||
|
Are you sure you want to enable developer mode? [y/n] `).then((response) => {
|
||||||
|
if (response === "y") {
|
||||||
|
developerMode = true;
|
||||||
|
console.log("Developer mode has been enabled")
|
||||||
|
}
|
||||||
|
res();
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
res();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
while (prompt) {
|
||||||
|
const input = await ask("> ");
|
||||||
|
switch (input) {
|
||||||
|
case "q":
|
||||||
|
case "quit": {
|
||||||
|
prompt = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "signup": {
|
||||||
|
let newUser = {};
|
||||||
|
|
||||||
|
// Get username, email, and password
|
||||||
|
while (1) {
|
||||||
|
newUser.name = await ask("Username: ");
|
||||||
|
|
||||||
|
let error = brainlet.valid.username(newUser.name);
|
||||||
|
if (error)
|
||||||
|
console.error(error);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
newUser.email = await ask("Email: ");
|
||||||
|
|
||||||
|
let error = brainlet.valid.email(newUser.email);
|
||||||
|
if (error)
|
||||||
|
console.error(error);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
newUser.password = await ask("Password: ");
|
||||||
|
|
||||||
|
let error = brainlet.valid.password(newUser.password);
|
||||||
|
if (error)
|
||||||
|
console.error(error);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
let confirmationPassword = await ask("Enter same password again: ");
|
||||||
|
if (confirmationPassword === newUser.password)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
console.error("Passwords do not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await promiseSucceeded(brainlet.users.create(server, newUser))) {
|
||||||
|
console.log("Account successfully created. To log in, use the \"login\" command");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "login": {
|
||||||
|
// Get username and password
|
||||||
|
while (1) {
|
||||||
|
user.name = await ask("Username: ");
|
||||||
|
|
||||||
|
let error = brainlet.valid.username(user.name);
|
||||||
|
if (error)
|
||||||
|
console.error(error);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
user.password = await ask("Password: ");
|
||||||
|
|
||||||
|
let error = brainlet.valid.password(user.password);
|
||||||
|
if (error)
|
||||||
|
console.error(error);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newUser = await catchErrors(brainlet.users.login(server, user));
|
||||||
|
|
||||||
|
if (newUser) {
|
||||||
|
newUser.password = undefined;
|
||||||
|
newUser.email = undefined;
|
||||||
|
|
||||||
|
user = newUser;
|
||||||
|
console.log("Successfully logged in, starting connection");
|
||||||
|
|
||||||
|
socket = await brainlet.categories.client(server, user.token);
|
||||||
|
console.log("Connection started");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "ls": {
|
||||||
|
if (!socket) {
|
||||||
|
console.error("You must log in before listing categories");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const limit = 5;
|
||||||
|
let categories = await catchErrors(brainlet.categories.list(server, user.token, limit));
|
||||||
|
|
||||||
|
if (categories) {
|
||||||
|
if (categories === limit) {
|
||||||
|
console.error(`Warning: This may be an incomplete list of categories`);
|
||||||
|
}
|
||||||
|
console.log("CATEGORY ID | CATEGORY TITLE");
|
||||||
|
for (let category of categories) {
|
||||||
|
console.log(`${category._id} | ${category.title}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "join": {
|
||||||
|
if (!socket) {
|
||||||
|
console.error("You must log in before joining a category");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let categoryID = await ask("Category ID: ");
|
||||||
|
await catchErrors(socket.connect([categoryID]));
|
||||||
|
console.log(`Successfully joined category ${categoryID}.
|
||||||
|
Anything typed will be sent to other users, unless it is prefixed with '/'.
|
||||||
|
To leave this category, use '/quit'`);
|
||||||
|
|
||||||
|
const PS1 = `${getColorCode(hexToRGB(user.color))}${user.name}${resetColorCode} [message currently not sent]: `;
|
||||||
|
socket.onMessage((message) => {
|
||||||
|
if (message.category._id === categoryID) {
|
||||||
|
process.stdout.write(`\r${clearLine}${getColorCode(hexToRGB(message.author.color))}${message.author.username}${resetColorCode}: ${message.content}\n${PS1}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let sendMessages = true;
|
||||||
|
while (sendMessages) {
|
||||||
|
const message = await ask(PS1);
|
||||||
|
switch (message) {
|
||||||
|
case "/leave": {
|
||||||
|
sendMessages = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
if (message[0] === "/") {
|
||||||
|
console.error(`${getColorCode([0xdd, 0, 0])}Invalid command ${message}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.send(categoryID, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "dump": {
|
||||||
|
await useDeveloperMode();
|
||||||
|
if (developerMode) {
|
||||||
|
console.log(user);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readline.close();
|
||||||
|
})();
|
18
package.json
Normal file
18
package.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "brainlet-cli",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "a better (unofficial) frontend for brainlet",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.hippoz.xyz/hiimgoodpack/brainlet-cli.git"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"dependencies": {
|
||||||
|
"readline": "^1.3.0"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue