Compare commits

..

No commits in common. "d1e34a5c103353457afa80d6d4ce8d53584594da" and "2f639b924a0c08f26ae7a738db5c38d713a66527" have entirely different histories.

7 changed files with 187 additions and 314 deletions

View File

@ -1,8 +1,8 @@
# Compiler and flags
CPPC = g++
CPPC_FLAGS = -std=c++23 -s -O3 -lncursesw -lcurl -lmenu -lpanel -Wall -Wextra -Wno-write-strings
CPPC_FLAGS = -std=c++23 -s -O3 -lncurses -lcurl -lmenu -lpanel -Wall -Wextra -Wno-write-strings
# Debug flags:
# CPPC_FLAGS = -ggdb -std=c++23 -lncursesw -lcurl -lmenu -lpanel -Wall -Wextra -Wno-write-strings
# CPPC_FLAGS = -ggdb -std=c++23 -lncurses -lcurl -lmenu -lpanel -Wall -Wextra
SRC_PATH := src
@ -35,4 +35,4 @@ $(OBJ_PATH)/%.o: $(SRC_PATH)/%.cpp
clean:
rm -fr build
.PHONY: all clean install
.PHONY: all clean make-build-dir

View File

@ -1,17 +1,14 @@
#include "helper_funcs.h"
#include "color.h"
#include "net.h"
#include <codecvt>
#include <csignal>
#include <curses.h>
#include <dirent.h>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <locale>
#include <string>
#include <termios.h>
#include <unistd.h>
#include "color.h"
void safe_exit(int code) {
switch (code) {
@ -47,47 +44,45 @@ std::string bool_to_string(bool bool_in) { return bool_in ? "true" : "false"; }
std::string SoRAuthFile(bool save, std::string data) {
std::string home = std::getenv("HOME");
if (home.empty()) {
std::cerr << RED "[ERROR] " RESET << "HOME environment variable not set.\n";
safe_exit(EXIT_FAILURE);
}
std::string savedir_path = home;
savedir_path.append("/.local/share/bakatui");
if (!std::filesystem::exists(savedir_path)) {
if (!std::filesystem::create_directories(savedir_path)) {
std::cerr << RED "[ERROR] " RESET
<< "Failed to create directory: " << savedir_path << "\n";
safe_exit(EXIT_FAILURE);
std::string home = std::getenv("HOME");
if (home.empty()) {
std::cerr << RED "[ERROR] " RESET << "HOME environment variable not set.\n";
safe_exit(EXIT_FAILURE);
}
}
std::string authfile_path = savedir_path + "/auth";
std::string savedir_path = home;
savedir_path.append("/.local/share/bakatui");
if (save) {
std::ofstream authfile(authfile_path);
if (!authfile.is_open()) {
std::cerr << RED "[ERROR] " RESET
<< "Failed to open auth file for writing.\n";
safe_exit(EXIT_FAILURE);
if (!std::filesystem::exists(savedir_path)) {
if (!std::filesystem::create_directories(savedir_path)) {
std::cerr << RED "[ERROR] " RESET << "Failed to create directory: " << savedir_path << "\n";
safe_exit(EXIT_FAILURE);
}
}
authfile << data;
authfile.close();
return "";
} else {
std::ifstream authfile(authfile_path);
if (!authfile.is_open()) {
std::cerr << RED "[ERROR] " RESET
<< "Failed to open auth file for reading.\n";
safe_exit(EXIT_FAILURE);
std::string authfile_path = savedir_path + "/auth";
if (save) {
std::ofstream authfile(authfile_path);
if (!authfile.is_open()) {
std::cerr << RED "[ERROR] " RESET << "Failed to open auth file for writing.\n";
safe_exit(EXIT_FAILURE);
}
authfile << data;
authfile.close();
return "";
} else {
std::ifstream authfile(authfile_path);
if (!authfile.is_open()) {
std::cerr << RED "[ERROR] " RESET << "Failed to open auth file for reading.\n";
safe_exit(EXIT_FAILURE);
}
data.assign((std::istreambuf_iterator<char>(authfile)),
std::istreambuf_iterator<char>());
authfile.close();
return data;
}
data.assign((std::istreambuf_iterator<char>(authfile)),
std::istreambuf_iterator<char>());
authfile.close();
return data;
}
}
void get_input_and_login() {
@ -104,7 +99,6 @@ void get_input_and_login() {
bakaapi::login(username, password);
}
// Original function
void print_in_middle(WINDOW *win, int starty, int startx, int width,
char *string, chtype color) {
int length, x, y;
@ -129,92 +123,19 @@ void print_in_middle(WINDOW *win, int starty, int startx, int width,
refresh();
}
// Wide character version
void wprint_in_middle(WINDOW *win, int starty, int startx, int width,
wchar_t *string, chtype color) {
int length, x, y;
float temp;
if (win == NULL)
win = stdscr;
getyx(win, y, x);
if (startx != 0)
x = startx;
if (starty != 0)
y = starty;
if (width == 0)
width = 80;
length = wcslen(string);
temp = (width - length) / 2;
x = startx + (int)temp;
wattron(win, color);
mvwaddwstr(win, y, x, string);
wattroff(win, color);
refresh();
}
const std::string WHITESPACE = " \n\r\t\f\v";
const std::wstring WWHITESPACE = L" \n\r\t\f\v";
std::string ltrim(const std::string &s) {
size_t start = s.find_first_not_of(WHITESPACE);
return (start == std::string::npos) ? "" : s.substr(start);
size_t start = s.find_first_not_of(WHITESPACE);
return (start == std::string::npos) ? "" : s.substr(start);
}
std::string rtrim(const std::string &s) {
size_t end = s.find_last_not_of(WHITESPACE);
return (end == std::string::npos) ? "" : s.substr(0, end + 1);
size_t end = s.find_last_not_of(WHITESPACE);
return (end == std::string::npos) ? "" : s.substr(0, end + 1);
}
std::string rm_tr_le_whitespace(const std::string &s) {
return rtrim(ltrim(s));
}
// Wide character versions
std::wstring wltrim(const std::wstring &s) {
size_t start = s.find_first_not_of(WWHITESPACE);
return (start == std::wstring::npos) ? L"" : s.substr(start);
}
std::wstring wrtrim(const std::wstring &s) {
size_t end = s.find_last_not_of(WWHITESPACE);
return (end == std::wstring::npos) ? L"" : s.substr(0, end + 1);
}
std::wstring wrm_tr_le_whitespace(const std::wstring &s) {
return wrtrim(wltrim(s));
}
// Conversion utilities
char *wchar_to_char(wchar_t *src) {
if (!src)
return nullptr;
size_t len = wcslen(src) + 1; // +1 for null terminator
char *dest = new char[len * MB_CUR_MAX];
std::wcstombs(dest, src, len * MB_CUR_MAX);
return dest;
}
wchar_t *char_to_wchar(char *src) {
if (!src)
return nullptr;
size_t len = strlen(src) + 1; // +1 for null terminator
wchar_t *dest = new wchar_t[len];
std::mbstowcs(dest, src, len);
return dest;
}
std::wstring string_to_wstring(const std::string &str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.from_bytes(str);
}
std::string wstring_to_string(const std::wstring &wstr) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.to_bytes(wstr);
return rtrim(ltrim(s));
}

View File

@ -9,22 +9,8 @@ void safe_exit(int code);
std::string bool_to_string(bool bool_in);
std::string SoRAuthFile(bool save, std::string data);
void get_input_and_login();
// Original functions
void print_in_middle(WINDOW *win, int starty, int startx, int width,
char *string, chtype color);
std::string rm_tr_le_whitespace(const std::string &s);
// Wide character support functions
void wprint_in_middle(WINDOW *win, int starty, int startx, int width,
wchar_t *string, chtype color);
std::wstring wrm_tr_le_whitespace(const std::wstring &s);
// Conversion utilities
char *wchar_to_char(wchar_t *src);
wchar_t *char_to_wchar(char *src);
std::wstring string_to_wstring(const std::string &str);
std::string wstring_to_string(const std::wstring &wstr);
#endif

View File

@ -1,25 +1,23 @@
#include "helper_funcs.h"
#include "net.h"
#include "timetable.h"
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <curses.h>
#include <locale>
#include <menu.h>
#include <string>
#include "marks.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define CTRLD 4
wchar_t *choices[] = {
L"login", L"Marks", L"timetable", L"Komens",
L"Homework", L"Absence", L"Exit", (wchar_t *)NULL,
char *choices[] = {
"login", "Marks", "timetable", "Komens",
"Homework", "Absence", "Exit", (char *)NULL,
};
void (*choicesFuncs[])() = {
nullptr, marks_page, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
};
void (*choicesFuncs[])() = {nullptr, marks_page, timetable_page, nullptr,
nullptr, nullptr, nullptr, nullptr};
void main_menu() {
ITEM **my_items;
@ -29,7 +27,6 @@ void main_menu() {
int n_choices, i;
/* Initialize curses */
setlocale(LC_ALL, "");
initscr();
start_color();
cbreak();
@ -42,8 +39,7 @@ void main_menu() {
n_choices = ARRAY_SIZE(choices);
my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
for (i = 0; i < n_choices; ++i)
my_items[i] =
new_item(wchar_to_char(choices[i]), wchar_to_char(choices[i]));
my_items[i] = new_item(choices[i], choices[i]);
/* Crate menu */
my_menu = new_menu((ITEM **)my_items);
@ -63,7 +59,7 @@ void main_menu() {
/* Print a border around the main window and print a title */
box(my_menu_win, 0, 0);
wprint_in_middle(my_menu_win, 1, 0, 40, L"Main Menu", COLOR_PAIR(1));
print_in_middle(my_menu_win, 1, 0, 40, "Main Menu", COLOR_PAIR(1));
mvwaddch(my_menu_win, 2, 0, ACS_LTEE);
mvwhline(my_menu_win, 2, 1, ACS_HLINE, 38);
mvwaddch(my_menu_win, 2, 39, ACS_RTEE);
@ -94,7 +90,7 @@ void main_menu() {
menu_driver(my_menu, REQ_UP_ITEM);
break;
case 10: // ENTER
clear();
clear();
choicesFuncs[item_index(current_item(my_menu))]();
pos_menu_cursor(my_menu);
refresh();
@ -110,4 +106,4 @@ void main_menu() {
for (i = 0; i < n_choices; ++i)
free_item(my_items[i]);
endwin();
}
}

View File

@ -1,7 +1,5 @@
#include "marks.h"
#include "helper_funcs.h"
#include "net.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdio>
@ -9,17 +7,40 @@
#include <curses.h>
#include <format>
#include <iostream>
#include <locale>
#include <menu.h>
#include <nlohmann/json.hpp>
#include <panel.h>
#include <string>
#include <algorithm>
#include "net.h"
using nlohmann::json;
// This code is based on
// Thsi code is based on
// https://github.com/tony/NCURSES-Programming-HOWTO-examples/blob/master/16-panels
// MIT License (see original file)
/*
The MIT License (MIT)
Copyright (c) 2016 Tony Narlock
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#define NLINES 10
#define NCOLS 40
@ -30,8 +51,8 @@ using nlohmann::json;
#define DEFAULT_PADDING 4
void init_wins(WINDOW **wins, int n, json marks_json);
void win_show(WINDOW *win, wchar_t *label, int label_color, int width,
int height, json marks_json, int SubjectIndex);
void win_show(WINDOW *win, char *label, int label_color, int width, int height,
json marks_json, int SubjectIndex);
void marks_page() {
// DONT FORGET TO UNCOMMENT
@ -77,8 +98,8 @@ void marks_page() {
// Attach panels
for (size_t i = 0; i < size_my_panels; i++) {
my_panels[i] = new_panel(my_wins[i]);
set_panel_userptr(my_panels[i], (i + 1 < size_my_panels) ? my_panels[i + 1]
: my_panels[0]);
set_panel_userptr(my_panels[i],
(i + 1 < size_my_panels) ? my_panels[i+1] : my_panels[0]);
}
update_panels();
@ -93,19 +114,19 @@ void marks_page() {
// Main loop
while ((ch = getch()) != KEY_F(1)) {
bool needs_update = false;
switch (ch) {
case KEY_UP:
case 'k': // Vim-style up
y_offset--;
needs_update = true;
break;
case KEY_UP:
case 'k': // Vim-style up
y_offset--;
needs_update = true;
break;
case KEY_DOWN:
case 'j': // Vim-style down
y_offset++;
needs_update = true;
break;
case KEY_DOWN:
case 'j': // Vim-style down
y_offset++;
needs_update = true;
break;
}
// Update window positions if scrolled
@ -115,7 +136,7 @@ void marks_page() {
int new_x = original_x[i];
move_panel(my_panels[i], new_y, new_x);
}
update_panels();
doupdate();
}
@ -133,48 +154,36 @@ void marks_page() {
/* Put all the windows */
void init_wins(WINDOW **wins, int n, json marks_json) {
int x, y, i;
wchar_t label[1500];
char label[1500];
y = DEFAULT_Y_OFFSET;
x = DEFAULT_X_OFFSET;
uint8_t curent_color = 0;
int MaxHight = 0;
// this loop through subjects
// this loop true subjects
for (i = 0; i < n; ++i) {
// Calculate label and max_text_length to determine window width
std::string sub_name = marks_json["Subjects"][i]["Subject"]["Name"];
// DEBUG
// std::clog << BLUE"[LOG]" << RESET" procesing subject: " << sub_name << "\n";
std::string sub_avg_s = marks_json["Subjects"][i]["AverageText"];
sprintf(label, "%s - avg: %s", sub_name.c_str(), sub_avg_s.c_str());
// Convert to wchar_t
std::wstring wsub_name = string_to_wstring(sub_name);
std::wstring wsub_avg_s = string_to_wstring(sub_avg_s);
// Using swprintf for wide character formatting
swprintf(label, sizeof(label) / sizeof(label[0]), L"%ls - avg: %ls",
wsub_name.c_str(), wsub_avg_s.c_str());
size_t max_text_length = wcslen(label);
size_t max_text_length = strlen(label);
for (int j = 0; j < marks_json["Subjects"][i]["Marks"].size(); j++) {
std::string caption =
rm_tr_le_whitespace(marks_json["Subjects"][i]["Marks"][j]["Caption"]);
std::string theme =
rm_tr_le_whitespace(marks_json["Subjects"][i]["Marks"][j]["Theme"]);
std::wstring wcaption = string_to_wstring(caption);
std::wstring wtheme = string_to_wstring(theme);
// Some code that does something and fixes some edge cases
std::string testCaption = caption + std::format(" {{{}}} [{}]", "X", 0);
std::wstring wTestCaption = string_to_wstring(testCaption);
std::string caption = rm_tr_le_whitespace(marks_json["Subjects"][i]["Marks"][j]["Caption"]);
std::string theme = rm_tr_le_whitespace(marks_json["Subjects"][i]["Marks"][j]["Theme"]);
caption = rm_tr_le_whitespace(caption);
theme = rm_tr_le_whitespace(theme);
max_text_length =
std::max({max_text_length, wTestCaption.length(), wtheme.length()});
std::max({max_text_length, caption.length(), theme.length()});
}
int width = max_text_length + DEFAULT_PADDING;
// handle windows overflowing off screen
// hanndle windows overflowing off screen
if (x + width > COLS) {
x = DEFAULT_X_OFFSET;
y += MaxHight + 2;
@ -198,8 +207,8 @@ void init_wins(WINDOW **wins, int n, json marks_json) {
}
/* Show the window with a border and a label */
void win_show(WINDOW *win, wchar_t *label, int label_color, int width,
int height, json marks_json, int SubjectIndex) {
void win_show(WINDOW *win, char *label, int label_color, int width, int height,
json marks_json, int SubjectIndex) {
int startx, starty;
wresize(win, height, width);
@ -212,49 +221,30 @@ void win_show(WINDOW *win, wchar_t *label, int label_color, int width,
mvwhline(win, 2, 1, ACS_HLINE, width - 2);
mvwaddch(win, 2, width - 1, ACS_RTEE);
wprint_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
wchar_t CaptionBuf[1500];
wchar_t ThemeBuf[1500];
std::wstring wCaption;
char CaptionBuf[1500];
char ThemeBuf[1500];
std::string Caption;
int AdditionalOffset = 0;
for (size_t i = 0; i < marks_json["Subjects"][SubjectIndex]["Marks"].size();
i++) {
std::string Caption =
marks_json["Subjects"][SubjectIndex]["Marks"][i]["Caption"];
Caption = marks_json["Subjects"][SubjectIndex]["Marks"][i]["Caption"];
Caption = rm_tr_le_whitespace(Caption);
Caption.append(std::format(" - {{{}}} [{}]",
marks_json["Subjects"][SubjectIndex]["Marks"][i]["MarkText"]
.get<std::string>(),marks_json["Subjects"][SubjectIndex]["Marks"][i]["Weight"].get<int>()));
strncpy(CaptionBuf, Caption.c_str(), sizeof(CaptionBuf)-1);
print_in_middle(win, 3 + i + AdditionalOffset, 0, width, CaptionBuf,COLOR_PAIR(label_color));
std::string MarkText =
marks_json["Subjects"][SubjectIndex]["Marks"][i]["MarkText"];
int Weight = marks_json["Subjects"][SubjectIndex]["Marks"][i]["Weight"];
// Create formatted string with mark and weight
std::string formattedCaption =
Caption + std::format(" - {{{}}} [{}]", MarkText, Weight);
// Convert to wide string
wCaption = string_to_wstring(formattedCaption);
wcsncpy(CaptionBuf, wCaption.c_str(),
sizeof(CaptionBuf) / sizeof(CaptionBuf[0]) - 1);
CaptionBuf[sizeof(CaptionBuf) / sizeof(CaptionBuf[0]) - 1] =
L'\0'; // Ensure null termination
wprint_in_middle(win, 3 + i + AdditionalOffset, 0, width, CaptionBuf,
COLOR_PAIR(label_color));
std::string Theme =
marks_json["Subjects"][SubjectIndex]["Marks"][i]["Theme"];
std::wstring wTheme = string_to_wstring(rm_tr_le_whitespace(Theme));
wcsncpy(ThemeBuf, wTheme.c_str(),
sizeof(ThemeBuf) / sizeof(ThemeBuf[0]) - 1);
ThemeBuf[sizeof(ThemeBuf) / sizeof(ThemeBuf[0]) - 1] =
L'\0'; // Ensure null termination
wprint_in_middle(win, 3 + i + 1 + AdditionalOffset, 0, width, ThemeBuf,
COLOR_PAIR(label_color));
strncpy(ThemeBuf,
rm_tr_le_whitespace(marks_json["Subjects"][SubjectIndex]["Marks"][i]["Theme"]
.get<std::string>())
.c_str(),
sizeof(ThemeBuf)-1);
print_in_middle(win, 3 + i + 1 + AdditionalOffset, 0, width, ThemeBuf,
COLOR_PAIR(label_color));
AdditionalOffset++;
}
}

View File

@ -1,6 +1,5 @@
#include "net.h"
#include "color.h"
#include "const.h"
#include "helper_funcs.h"
#include "main.h"
#include <cerrno>
@ -17,6 +16,7 @@
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>
#include <string>
#include "const.h"
using nlohmann::json;
@ -38,8 +38,9 @@ size_t WriteCallback(void *contents, size_t size, size_t nmemb,
return totalSize;
}
std::tuple<std::string, int>
send_curl_request(std::string endpoint, uint8_t type, std::string req_data) {
std::tuple<std::string, int> send_curl_request(std::string endpoint,
uint8_t type,
std::string req_data) {
std::string response;
std::string url = baka_api_url + endpoint;
if (type == GET) {
@ -53,32 +54,28 @@ send_curl_request(std::string endpoint, uint8_t type, std::string req_data) {
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
if (config.ignoressl) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
}
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
struct curl_slist *headers = NULL;
headers = curl_slist_append(
headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(
headers, std::format("User-Agent: bakatui/{}", VERSION).c_str());
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(headers, std::format("User-Agent: bakatui/{}", VERSION).c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
switch (type) {
case GET:
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
break;
case POST:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_data.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L);
break;
default:
std::cerr << RED "[ERROR] " << RESET "invalid metod\n";
safe_exit(EINVAL);
case GET:
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
break;
case POST:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_data.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L);
break;
default:
std::cerr << RED "[ERROR] " << RESET "invalid metod\n";
safe_exit(EINVAL);
}
} else {
@ -90,6 +87,8 @@ send_curl_request(std::string endpoint, uint8_t type, std::string req_data) {
int http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
return {response, http_code};
}
namespace bakaapi {
@ -112,7 +111,7 @@ void login(std::string username, std::string password) {
{
std::string savedir_path = std::getenv("HOME");
savedir_path.append("/.local/share/bakatui");
std::string urlfile_path = std::string(savedir_path) + "/url";
std::ofstream urlfile;
urlfile.open(urlfile_path);
@ -142,8 +141,7 @@ void refresh_access_token() {
refresh_token);
// DEBUG
std::clog << "calling send_curl_request() with folowing req_data\n"
<< req_data << std::endl;
std::clog << "calling send_curl_request() with folowing req_data\n" << req_data << std::endl;
auto [response, http_code] = send_curl_request("api/login", POST, req_data);
if (http_code != 200) {
std::cerr << RED "[ERROR] " << RESET << http_code
@ -158,28 +156,27 @@ void refresh_access_token() {
access_token = resp_parsed["access_token"];
}
void is_access_token_empty() {
if (access_token.empty()) {
if(access_token.empty()) {
json authfile_parsed = json::parse(SoRAuthFile(false, ""));
access_token = authfile_parsed["access_token"];
}
}
}
// supports all endpoints that only require access_token
json get_data_from_endpoint(std::string endpoint) {
is_access_token_empty();
std::string req_data =
std::format("Authorization=Bearer&access_token={}", access_token);
is_access_token_empty();
std::string req_data =
std::format("Authorization=Bearer&access_token={}",
access_token);
auto [response, http_code] = send_curl_request(endpoint, GET, req_data);
auto [response, http_code] = send_curl_request(endpoint, GET, req_data);
if (http_code != 200) {
// DEBUG
std::clog << "Failed geting data from endpoint: " << endpoint
<< " code: " << http_code << "\nrequest: " << req_data
<< "\nresponse: " << response << std::endl;
refresh_access_token();
}
if(http_code != 200) {
// DEBUG
std::clog << "Failed geting data from endpoint: " << endpoint << " code: " << http_code << "\nrequest: " << req_data <<"\nresponse: " << response << std::endl;
refresh_access_token();
}
return json::parse(response);
return json::parse(response);
}
} // namespace bakaapi

View File

@ -1,49 +1,32 @@
#include "timetable.h"
#include "net.h"
#include <cstdint>
#include <format>
#include <fstream>
#include <iostream>
#include <locale>
#include <ncurses.h>
#include <nlohmann/json.hpp>
#include "net.h"
#include <fstream>
using nlohmann::json;
#define NLINES 10
#define NCOLS 40
#define DEFAULT_X_OFFSET 10
#define DEFAULT_Y_OFFSET 2
#define DEFAULT_PADDING 4
void timetable_page() {
// DONT FORGET TO UNCOMMENT
// json resp_from_api =
// bakaapi::get_data_from_endpoint("api/3/timetable/actual");
std::ifstream f("test-data/timetable.json");
json resp_from_api = json::parse(f);
// DONT FORGET TO UNCOMMENT
// json resp_from_api = bakaapi::get_data_from_endpoint("api/3/timetable/actual");
std::ifstream f("test-data/timetable.json");
json resp_from_api = json::parse(f);
// calculate table size
// some lambda dark magic
const uint8_t num_of_columns = [&]() -> uint8_t {
uint8_t result = 0;
for (uint8_t i = 0; i < resp_from_api["Days"].size(); i++) {
uint8_t currentSize = resp_from_api["Days"][i]["Atoms"].size();
if (currentSize > result) {
result = currentSize;
}
// calculate table size
uint8_t column_number = 0;
for(uint8_t i = 0; i < resp_from_api["Days"].size(); i++) {
(resp_from_api["Days"][i]["Atoms"].size() > column_number) ? (column_number = resp_from_api["Days"][i]["Atoms"].size());
}
return result;
}();
const uint8_t num_of_rows = resp_from_api["Days"].size();
setlocale(LC_ALL, "");
/* Initialize curses */
initscr();
start_color();
cbreak();
noecho();
keypad(stdscr, TRUE);
// Use wide character printing
std::wstring msg = std::format(L"LINES: {} COLS: {}", LINES, COLS);
mvaddwstr(0, 0, msg.c_str());
refresh();
getch(); // Wait for key press
endwin();
}