Skip to content

Commit 8b0869b

Browse files
committed
Update
1 parent 24cef43 commit 8b0869b

File tree

3 files changed

+158
-74
lines changed

3 files changed

+158
-74
lines changed

client.cpp

Lines changed: 131 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,127 @@ using std::string, std::vector, nlohmann::json;
1818
namespace fs = std::filesystem;
1919
namespace ch = std::chrono;
2020

21-
char drawUI(string title, vector<string> arr) {
22-
noecho();
23-
short choice = 0, ch;
24-
bool kurwa = true;
25-
while (kurwa) {
26-
printw("%s\n", title.c_str());
27-
for (int i = 0; i < arr.size(); i++)
28-
printw("%c %s\n", i == choice ? '>' : ' ', arr[i].c_str());
29-
switch (ch = getch()) {
30-
case 'k':
31-
case KEY_UP:
32-
if (choice > 0) choice--;
33-
break;
34-
case 'j':
35-
case KEY_DOWN:
36-
if (choice < arr.size() - 1) choice++;
37-
break;
38-
case '\n':
39-
kurwa = false;
40-
break;
21+
class clsUi {
22+
public:
23+
short maxx, maxy;
24+
25+
short menu(const string& title, const vector<string>& choices) {
26+
noecho();
27+
curs_set(false);
28+
short choice = 0, input = 0, maxWidth = 0, maxHeight = choices.size(),
29+
minWidth = 15;
30+
for (const string& str : choices) {
31+
short len = str.length();
32+
if (len > maxWidth) maxWidth = len;
4133
}
42-
clear();
34+
short titleLen = title.length();
35+
if (titleLen > maxWidth) maxWidth = titleLen;
36+
if (minWidth > maxWidth) maxWidth = minWidth;
37+
WINDOW* win =
38+
newwin(maxHeight + 2, maxWidth + 2, maxy / 2 - (maxHeight + 2) / 2,
39+
maxx / 2 - (maxWidth + 2) / 2);
40+
keypad(win, true);
41+
box(win, 0, 0);
42+
mvwprintw(win, 0, 1, "%s", title.c_str());
43+
for (int i = 1; i < choices.size(); i++)
44+
mvwprintw(win, i + 1, 1, "%s", choices[i].c_str());
45+
do {
46+
switch (input) {
47+
case 'k':
48+
case KEY_UP:
49+
if (choice > 0) {
50+
mvwprintw(win, choice + 1, 1, "%s%*c",
51+
choices[choice].c_str(),
52+
maxWidth - choices[choice].length() + 1,
53+
'\0');
54+
--choice;
55+
}
56+
break;
57+
case 'j':
58+
case KEY_DOWN:
59+
if (choice < choices.size() - 1) {
60+
mvwprintw(win, choice + 1, 1, "%s%*c",
61+
choices[choice].c_str(),
62+
maxWidth - choices[choice].length() + 1,
63+
'\0');
64+
++choice;
65+
}
66+
break;
67+
default:
68+
break;
69+
}
70+
wattron(win, A_STANDOUT);
71+
mvwprintw(win, choice + 1, 1, "%s%*c", choices[choice].c_str(),
72+
maxWidth - choices[choice].length() + 1, '\0');
73+
wattroff(win, A_STANDOUT);
74+
} while ((input = wgetch(win)) != '\n');
75+
werase(win);
76+
wrefresh(win);
77+
delwin(win);
78+
echo();
79+
curs_set(true);
80+
return choice;
4381
}
44-
echo();
45-
return choice;
46-
}
47-
void progressBar(const long &prog, const long &total) {
48-
int y, x;
49-
getyx(stdscr, y, x);
50-
const int len = 30;
51-
int percent = ceil(float(len) / total * prog);
52-
wchar_t str[len + 1];
53-
for (int i = 0; i < percent; i++) str[i] = L'\u2588';
54-
for (int i = percent; i < len; i++) str[i] = L'\u2592';
55-
str[len] = L'\0';
56-
mvprintw(y, 0, "|%ls|", str);
57-
if (prog == total) addch('\n');
58-
refresh();
59-
}
82+
83+
void progressBar(const long& prog, const long& total) {
84+
short y, x;
85+
getyx(stdscr, y, x);
86+
const int len = 30;
87+
short percent = ceil(float(len) / total * prog);
88+
wchar_t str[len + 1];
89+
for (short i = 0; i < percent; i++) str[i] = L'\u2588';
90+
for (short i = percent; i < len; i++) str[i] = L'\u2592';
91+
str[len] = L'\0';
92+
mvprintw(y, 0, "|%ls|", str);
93+
if (prog == total) move(y + 1, 0);
94+
refresh();
95+
}
96+
97+
void notification(const string& title, const vector<string>& message) {
98+
noecho();
99+
curs_set(false);
100+
short maxWidth = 0, maxHeight = message.size(),
101+
titleLen = title.length();
102+
for (const string& str : message) {
103+
short len = str.length();
104+
if (len > maxWidth) maxWidth = len;
105+
}
106+
if (titleLen > maxWidth) maxWidth = titleLen;
107+
maxWidth += 4;
108+
WINDOW* win =
109+
newwin(maxHeight + 2, maxWidth, maxy / 2 - (maxHeight + 2) / 2,
110+
maxx / 2 - maxWidth / 2);
111+
box(win, 0, 0);
112+
mvwprintw(win, 0, maxWidth / 2 - titleLen / 2, "%s", title.c_str());
113+
for (short i = 0; i < maxHeight; i++)
114+
mvwprintw(win, i + 1, maxWidth / 2 - message[i].length() / 2, "%s",
115+
message[i].c_str());
116+
wrefresh(win);
117+
118+
wgetch(win);
119+
werase(win);
120+
wrefresh(win);
121+
delwin(win);
122+
123+
echo();
124+
curs_set(true);
125+
}
126+
127+
clsUi() {
128+
setlocale(LC_ALL, "");
129+
initscr();
130+
cbreak();
131+
scrollok(stdscr, true);
132+
keypad(stdscr, true);
133+
getmaxyx(stdscr, maxy, maxx);
134+
}
135+
~clsUi() { endwin(); }
136+
};
60137

61138
class client {
62139
public:
63140
clsSock sock;
141+
clsUi ui;
64142

65143
void reg() {
66144
char buffer[1024];
@@ -88,14 +166,14 @@ class client {
88166
clear();
89167
} while (sock.recv() != "ok");
90168
}
91-
client(SSL *ssl) : sock(ssl) {}
169+
client(SSL* ssl, clsUi& ui) : sock(ssl), ui(ui) {}
92170
};
93171

94172
class project {
95173
private:
96174
json genJson(string path) {
97175
json res;
98-
for (const fs::directory_entry &entry : fs::directory_iterator(path)) {
176+
for (const fs::directory_entry& entry : fs::directory_iterator(path)) {
99177
if (entry.is_directory())
100178
res[entry.path().filename().string()] =
101179
genJson(entry.path().string());
@@ -108,7 +186,7 @@ class project {
108186
return res;
109187
}
110188

111-
void compJson(json &oldjs, json &newjs, string path) {
189+
void compJson(json& oldjs, json& newjs, string path) {
112190
for (json::iterator it = oldjs.begin(); it != oldjs.end(); ++it) {
113191
if (newjs.contains(it.key())) {
114192
if (it.value().is_number() && newjs[it.key()].is_object()) {
@@ -183,12 +261,13 @@ class project {
183261

184262
void set() {
185263
char buffer[1024];
186-
do {
264+
/* do {
187265
printw("Path to your project: ");
188266
getstr(buffer);
189267
prjPath = buffer;
190-
} while (!fs::exists(prjPath) && !fs::is_directory(prjPath));
191-
// prjPath = "/home/jomm/Documents/kurwa/client/test/";
268+
} while (!fs::exists(prjPath) && !fs::is_directory(prjPath)); */
269+
prjPath = "/home/jomm/Documents/kurwa/client/test/";
270+
// prjPath += '/';
192271
do {
193272
printw("Name of your project: ");
194273
getstr(buffer);
@@ -229,10 +308,10 @@ class project {
229308
}
230309
}
231310

232-
project(client &x) : owner(x) {}
311+
project(client& x) : owner(x) {}
233312
};
234313

235-
int main(int argc, char *argv[]) {
314+
int main(int argc, char* argv[]) {
236315
string path = fs::canonical(argv[0]).parent_path().string() + '/';
237316

238317
setlocale(LC_ALL, "");
@@ -241,13 +320,14 @@ int main(int argc, char *argv[]) {
241320
keypad(stdscr, TRUE);
242321

243322
SSL_library_init();
244-
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
323+
SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
245324

246325
SSL_CTX_load_verify_locations(ctx, (path + "cert.pem").c_str(), NULL);
247326

248-
client client(SSL_new(ctx));
327+
clsUi ui;
328+
client client(SSL_new(ctx), ui);
249329

250-
switch (drawUI("Choose one option:", {"Sign In", "Sign Up"})) {
330+
switch (ui.menu("Choose one option:", {"Sign In", "Sign Up"})) {
251331
case 0:
252332
client.sock.send("signIn");
253333
client.log();
@@ -259,9 +339,9 @@ int main(int argc, char *argv[]) {
259339
break;
260340
}
261341
project project(client);
262-
switch (drawUI("Choose one option:",
263-
{"Create new project", "Open existing project",
264-
"Download project from server"})) {
342+
switch (ui.menu("Choose one option:",
343+
{"Create new project", "Open existing project",
344+
"Download project from server"})) {
265345
case 0:
266346
client.sock.send("createPrj");
267347
project.set();

server.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@
2424
using std::string, std::thread, std::ref, std::cout, std::endl;
2525
namespace fs = std::filesystem;
2626

27-
class clsDb {
27+
class db {
2828
private:
29-
sqlite3* db;
29+
sqlite3* database;
3030

3131
public:
3232
bool exec(const string& query, const string& types, ...) {
3333
va_list args;
3434
va_start(args, types);
3535
sqlite3_stmt* stmt;
36-
sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, 0);
36+
sqlite3_prepare_v2(database, query.c_str(), -1, &stmt, 0);
3737

3838
short toBind = 0;
3939
for (char ch : query)
@@ -87,11 +87,11 @@ class clsDb {
8787
return found;
8888
}
8989

90-
clsDb(const string& path, const string& command) {
91-
sqlite3_open(path.c_str(), &db);
92-
sqlite3_exec(db, command.c_str(), 0, 0, 0);
90+
db(const string& path, const string& command) {
91+
sqlite3_open(path.c_str(), &database);
92+
sqlite3_exec(database, command.c_str(), 0, 0, 0);
9393
}
94-
~clsDb() { sqlite3_close(db); }
94+
~db() { sqlite3_close(database); }
9595
};
9696

9797
class client {
@@ -108,7 +108,7 @@ class client {
108108
clsSock sock;
109109
unsigned long id = 0;
110110

111-
void reg(clsDb& db) {
111+
void reg(db& db) {
112112
string sBuffer;
113113
string username;
114114
while (username.empty()) {
@@ -128,7 +128,7 @@ class client {
128128
cout << "[+] New user created." << endl;
129129
}
130130

131-
void log(clsDb& db) {
131+
void log(db& db) {
132132
while (!id) {
133133
string username = sock.recv();
134134
string password = sock.recv();
@@ -168,7 +168,7 @@ class project {
168168
string prjPath;
169169
unsigned long prjId = 0;
170170

171-
void create(clsDb& db) {
171+
void create(db& db) {
172172
while (!prjId) {
173173
string prjName = owner.sock.recv();
174174
if (!db.exec("select id from projects where ownerId = ? and "
@@ -179,6 +179,7 @@ class project {
179179
char uuidStr[37];
180180
uuid_unparse(uuid, uuidStr);
181181
prjPath = prjPath + uuidStr + '/';
182+
cout << prjPath << endl;
182183
fs::create_directory(prjPath);
183184
db.exec(
184185
"insert into projects (ownerId, prjName, dir, dirTree) "
@@ -194,27 +195,29 @@ class project {
194195
}
195196
}
196197

197-
void set(clsDb& db) {
198+
void set(db& db) {
198199
while (!prjId) {
199200
string uuid;
200201
if (db.exec("select id, dir from projects where ownerId = ? "
201202
"and prjName = ?;",
202203
"isis", owner.id, owner.sock.recv().c_str(), &prjId,
203204
&uuid)) {
204205
prjPath = prjPath + uuid + '/';
206+
cout << prjPath << endl;
205207
owner.sock.send("ok");
206208
} else
207209
owner.sock.send("not ok");
208210
}
209211
}
210212

211-
void open(clsDb& db) {
213+
void open(db& db) {
212214
string command;
213215
while ((command = owner.sock.recv()) != "quit") {
214216
if (command == "push") {
215217
string dirTree;
216218
db.exec("select dirTree from projects where id = ?;", "si",
217219
prjId, &dirTree);
220+
cout << dirTree << endl;
218221
owner.sock.send(dirTree);
219222
while ((command = owner.sock.recv())[0] != '{') {
220223
string action = command.substr(0, command.find(' '));
@@ -248,7 +251,7 @@ class project {
248251
project(client& x, const string& y) : owner(x), prjPath(y) {}
249252
};
250253

251-
void handleClient(client client, clsDb& db, const string& path) {
254+
void handleClient(client client, db& db, const string& path) {
252255
cout << "[+] Kurwa client connected." << endl;
253256
string command = client.sock.recv();
254257
if (command == "signUp") {
@@ -277,7 +280,7 @@ int main(int argc, char* argv[]) {
277280
signal(SIGPIPE, SIG_IGN);
278281
const string path = fs::canonical(argv[0]).parent_path().string() + '/';
279282

280-
clsDb db(
283+
db db(
281284
path + "users.db",
282285
"create table if not exists users (id integer primary key, username "
283286
"text, password blob); create table if not exists projects (id integer "
@@ -300,11 +303,12 @@ int main(int argc, char* argv[]) {
300303

301304
listen(servSock, 5);
302305
cout << "[!] Everything is ok :)" << endl;
303-
while (true) {
304-
client newClient(accept(servSock, (sockaddr*)&servAddr, &addrLen),
305-
SSL_new(ctx));
306-
thread(handleClient, newClient, ref(db), path).detach();
307-
}
306+
while (true)
307+
thread(handleClient,
308+
client(accept(servSock, (sockaddr*)&servAddr, &addrLen),
309+
SSL_new(ctx)),
310+
ref(db), path)
311+
.detach();
308312

309313
SSL_CTX_free(ctx);
310314
close(servSock);

0 commit comments

Comments
 (0)