Mercurial > minori
changeset 11:fc1bf97c528b
*: use C++11 standard
I've been meaning to do this for a while, but I didn't want to reimplement
the filesystem code. Now we are on C++11 and most compilers from the past 5 centuries should support this now
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Sun, 17 Sep 2023 06:14:30 -0400 |
parents | 4b198a111713 |
children | cf6a73a5ba1c |
files | CMakeLists.txt include/core/anime_db.h include/core/config.h include/core/filesystem.h src/core/anime_db.cpp src/core/config.cpp src/core/date.cpp src/core/filesystem.cpp src/gui/dialog/settings/services.cpp src/gui/pages/anime_list.cpp src/gui/pages/statistics.cpp src/gui/sidebar.cpp src/main.cpp src/services/anilist.cpp |
diffstat | 14 files changed, 146 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Sat Sep 16 02:06:01 2023 -0400 +++ b/CMakeLists.txt Sun Sep 17 06:14:30 2023 -0400 @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(weeaboo LANGUAGES CXX OBJCXX) +project(minori LANGUAGES CXX OBJCXX) add_subdirectory(dep/anitomy) @@ -54,10 +54,10 @@ list(APPEND SRC_FILES src/sys/win32/dark_theme.cpp) endif() -add_executable(weeaboo ${SRC_FILES}) -set_property(TARGET weeaboo PROPERTY CXX_STANDARD 20) -set_property(TARGET weeaboo PROPERTY AUTOMOC ON) -set_property(TARGET weeaboo PROPERTY AUTORCC ON) +add_executable(minori ${SRC_FILES}) +set_property(TARGET minori PROPERTY CXX_STANDARD 11) +set_property(TARGET minori PROPERTY AUTOMOC ON) +set_property(TARGET minori PROPERTY AUTORCC ON) find_package(Qt5 COMPONENTS Widgets Test REQUIRED) find_package(CURL REQUIRED) @@ -74,11 +74,11 @@ list(APPEND LIBRARIES ${COCOA_LIBRARY}) endif() -target_include_directories(weeaboo PUBLIC ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Test_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} PRIVATE include) -target_compile_options(weeaboo PRIVATE -Wall -Wextra -Wsuggest-override) +target_include_directories(minori PUBLIC ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Test_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} PRIVATE include) +target_compile_options(minori PRIVATE -Wall -Wextra -Wsuggest-override) if(APPLE) - target_compile_definitions(weeaboo PUBLIC MACOSX) + target_compile_definitions(minori PUBLIC MACOSX) elseif(WIN32) - target_compile_definitions(weeaboo PUBLIC WIN32) + target_compile_definitions(minori PUBLIC WIN32) endif() -target_link_libraries(weeaboo ${LIBRARIES}) +target_link_libraries(minori ${LIBRARIES})
--- a/include/core/anime_db.h Sat Sep 16 02:06:01 2023 -0400 +++ b/include/core/anime_db.h Sun Sep 17 06:14:30 2023 -0400 @@ -17,7 +17,7 @@ int GetListsAnimeAmount(ListStatus status); }; -inline Database db; +extern Database db; } // namespace Anime #endif // __core__anime_db_h
--- a/include/core/config.h Sat Sep 16 02:06:01 2023 -0400 +++ b/include/core/config.h Sun Sep 17 06:14:30 2023 -0400 @@ -32,7 +32,8 @@ int user_id; } anilist; }; -#define CONFIG_DIR "weeaboo" + +#define CONFIG_DIR "minori" #define CONFIG_NAME "config.json" #define MAX_LINE_LENGTH 256 #endif // __core__config_h
--- a/include/core/filesystem.h Sat Sep 16 02:06:01 2023 -0400 +++ b/include/core/filesystem.h Sun Sep 17 06:14:30 2023 -0400 @@ -1,5 +1,14 @@ #ifndef __core__filesystem_h #define __core__filesystem_h -#include <filesystem> -std::filesystem::path get_config_path(void); -#endif // __core__filesystem_h \ No newline at end of file +#include <string> + +namespace Filesystem { + +bool CreateDirectories(std::string path); +bool Exists(std::string path); +std::string GetParentDirectory(std::string path); +std::string GetConfigPath(); + +} + +#endif // __core__filesystem_h
--- a/src/core/anime_db.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/core/anime_db.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -5,8 +5,8 @@ int Database::GetTotalAnimeAmount() { int total = 0; - for (const auto& [id, anime] : items) { - if (anime.IsInUserList()) + for (const auto& a : items) { + if (a.second.IsInUserList()) total++; } return total; @@ -16,8 +16,8 @@ if (status == ListStatus::NOT_IN_LIST) return 0; int total = 0; - for (const auto& [id, anime] : items) { - if (anime.IsInUserList() && anime.GetUserStatus() == status) + for (const auto& a : items) { + if (a.second.IsInUserList() && a.second.GetUserStatus() == status) total++; } return total; @@ -25,10 +25,10 @@ int Database::GetTotalEpisodeAmount() { int total = 0; - for (const auto& [id, anime] : items) { - if (anime.IsInUserList()) { - total += anime.GetUserRewatchedTimes() * anime.GetEpisodes(); - total += anime.GetUserProgress(); + for (const auto& a : items) { + if (a.second.IsInUserList()) { + total += a.second.GetUserRewatchedTimes() * a.second.GetEpisodes(); + total += a.second.GetUserProgress(); } } return total; @@ -37,10 +37,10 @@ /* Returns the total watched amount in minutes. */ int Database::GetTotalWatchedAmount() { int total = 0; - for (const auto& [id, anime] : items) { - if (anime.IsInUserList()) { - total += anime.GetDuration() * anime.GetUserProgress(); - total += anime.GetEpisodes() * anime.GetDuration() * anime.GetUserRewatchedTimes(); + for (const auto& a : items) { + if (a.second.IsInUserList()) { + total += a.second.GetDuration() * a.second.GetUserProgress(); + total += a.second.GetEpisodes() * a.second.GetDuration() * a.second.GetUserRewatchedTimes(); } } return total; @@ -53,9 +53,9 @@ rather be handled elsewhere. */ int Database::GetTotalPlannedAmount() { int total = 0; - for (const auto& [id, anime] : items) { - if (anime.IsInUserList()) - total += anime.GetDuration() * (anime.GetEpisodes() - anime.GetUserProgress()); + for (const auto& a : items) { + if (a.second.IsInUserList()) + total += a.second.GetDuration() * (a.second.GetEpisodes() - a.second.GetUserProgress()); } return total; } @@ -65,9 +65,9 @@ double Database::GetAverageScore() { double avg = 0; int amt = 0; - for (const auto& [id, anime] : items) { - if (anime.IsInUserList() && anime.GetUserScore()) { - avg += anime.GetUserScore(); + for (const auto& a : items) { + if (a.second.IsInUserList() && a.second.GetUserScore()) { + avg += a.second.GetUserScore(); amt++; } } @@ -77,13 +77,15 @@ double Database::GetScoreDeviation() { double squares_sum = 0, avg = GetAverageScore(); int amt = 0; - for (const auto& [id, anime] : items) { - if (anime.GetUserScore()) { - squares_sum += std::pow((double)anime.GetUserScore() - avg, 2); + for (const auto& a : items) { + if (a.second.IsInUserList() && a.second.GetUserScore()) { + squares_sum += std::pow((double)a.second.GetUserScore() - avg, 2); amt++; } } return (amt > 0) ? std::sqrt(squares_sum / amt) : 0; } +Database db; + } // namespace Anime \ No newline at end of file
--- a/src/core/config.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/core/config.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -47,11 +47,11 @@ }; int Config::Load() { - std::filesystem::path cfg_path = get_config_path(); - if (!std::filesystem::exists(cfg_path)) + std::string cfg_path = Filesystem::GetConfigPath(); + if (!Filesystem::Exists(cfg_path)) return 0; - std::ifstream config_in(cfg_path.string().c_str(), std::ifstream::in); - auto config_js = nlohmann::json::parse(config_in); + std::ifstream config(cfg_path.c_str(), std::ifstream::in); + auto config_js = nlohmann::json::parse(config); service = StringToService[JSON::GetString(config_js, "/General/Service"_json_pointer)]; anime_list.language = StringToAnimeTitleMap[JSON::GetString( config_js, "/Anime List/Display only aired episodes"_json_pointer, "Romaji")]; @@ -67,15 +67,15 @@ anilist.username = JSON::GetString(config_js, "/Authorization/AniList/Username"_json_pointer); anilist.user_id = JSON::GetInt(config_js, "/Authorization/AniList/User ID"_json_pointer); theme = StringToTheme[JSON::GetString(config_js, "/Appearance/Theme"_json_pointer)]; - config_in.close(); + config.close(); return 0; } int Config::Save() { - std::filesystem::path cfg_path = get_config_path(); - if (!std::filesystem::exists(cfg_path.parent_path())) - std::filesystem::create_directories(cfg_path.parent_path()); - std::ofstream config_out(cfg_path.string().c_str(), std::ofstream::out | std::ofstream::trunc); + std::string cfg_path = Filesystem::GetConfigPath(); + if (!Filesystem::Exists(Filesystem::GetParentDirectory(cfg_path))) + Filesystem::CreateDirectories(Filesystem::GetParentDirectory(cfg_path)); + std::ofstream config(cfg_path.c_str(), std::ofstream::out | std::ofstream::trunc); // clang-format off nlohmann::json config_js = { {"General", { @@ -100,7 +100,7 @@ }} }; // clang-format on - config_out << std::setw(4) << config_js << std::endl; - config_out.close(); + config << std::setw(4) << config_js << std::endl; + config.close(); return 0; }
--- a/src/core/date.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/core/date.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -31,13 +31,13 @@ } Date::Date(int32_t y) { - year = std::make_unique<int32_t>(MAX(0, y)); + SetYear(y); } Date::Date(int32_t y, int8_t m, int8_t d) { - year = std::make_unique<int32_t>(MAX(0, y)); - month = std::make_unique<int8_t>(CLAMP(m, 1, 12)); - day = std::make_unique<int8_t>(CLAMP(d, 1, 31)); + SetYear(y); + SetMonth(m); + SetDay(d); } void Date::VoidYear() { @@ -53,15 +53,15 @@ } void Date::SetYear(int32_t y) { - year = std::make_unique<int32_t>(MAX(0, y)); + year.reset(new int32_t(MAX(0, y))); } void Date::SetMonth(int8_t m) { - month = std::make_unique<int8_t>(CLAMP(m, 1, 12)); + month.reset(new int8_t(CLAMP(m, 1, 12))); } void Date::SetDay(int8_t d) { - day = std::make_unique<int8_t>(CLAMP(d, 1, 31)); + day.reset(new int8_t(CLAMP(d, 1, 31))); } int32_t Date::GetYear() const {
--- a/src/core/filesystem.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/core/filesystem.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -5,31 +5,82 @@ #elif defined(__linux__) #include <pwd.h> #include <sys/types.h> -#include <unistd.h> #endif -#include "core/config.h" + +#ifdef WIN32 +#define DELIM "\\" +#else +#define DELIM "/" +#include <unistd.h> +#include <errno.h> +#endif + #include "core/filesystem.h" -#include "core/strings.h" -#include <QMessageBox> -#include <filesystem> +#include "core/config.h" #include <limits.h> -std::filesystem::path get_config_path(void) { - std::filesystem::path cfg_path; +namespace Filesystem { + +bool CreateDirectories(std::string path) { + std::string temp = ""; + size_t start; + size_t end = 0; + + while ((start = path.find_first_not_of(DELIM, end)) != std::string::npos) + { + end = path.find(DELIM, start); + temp.append(path.substr(start, end - start)); +#ifdef WIN32 + if (!CreateDirectoryA(temp.c_str(), NULL) && GetLastError() == ERROR_PATH_NOT_FOUND) + /* ERROR_PATH_NOT_FOUND should NOT happen here */ + return false; +#else + if (mkdir(temp.c_str(), 0755)) + return false; +#endif + temp.append(DELIM); + } + return true; +} + +bool Exists(std::string path) { +#if WIN32 + return GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES; +#else + struct stat st; + return stat(path.c_str(), &st) == 0; +#endif +} + +std::string GetParentDirectory(std::string path) { + size_t pos = 0; + pos = path.find_last_of(DELIM); + return path.substr(0, pos); +} + +std::string GetConfigPath(void) { + std::string ret = ""; #ifdef WIN32 char buf[PATH_MAX + 1]; - if (SHGetFolderPathAndSubDir(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, CONFIG_DIR, buf) == S_OK) - cfg_path = std::filesystem::path(buf) / CONFIG_NAME; + if (SHGetFolderPathAndSubDir(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, CONFIG_DIR, buf) == S_OK) { + ret += buf; + ret += DELIM CONFIG_NAME; + } #elif defined(MACOSX) - /* pass all of our problems to */ - cfg_path = std::filesystem::path(osx::GetApplicationSupportDirectory()) / CONFIG_DIR / CONFIG_NAME; + /* pass all of our problems to objc++ code */ + ret += osx::GetApplicationSupportDirectory(); + ret += DELIM CONFIG_DIR DELIM CONFIG_NAME; #else // just assume POSIX if (getenv("HOME") != NULL) - cfg_path = std::filesystem::path(getenv("HOME")) / ".config" / CONFIG_DIR / CONFIG_NAME; + ret += getenv("HOME"); #ifdef __linux__ else - cfg_path = std::filesystem::path(getpwuid(getuid())->pw_dir) / ".config" / CONFIG_DIR / CONFIG_NAME; + ret += getpwuid(getuid())->pw_dir; #endif // __linux__ + if (!ret.empty()) + ret += DELIM ".config" DELIM CONFIG_DIR DELIM CONFIG_NAME; #endif // !WIN32 && !MACOSX - return cfg_path; + return ret; } + +}
--- a/src/gui/dialog/settings/services.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/gui/dialog/settings/services.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -23,7 +23,7 @@ sync_combo_box->setCurrentIndex(static_cast<int>(service) - 1); QLabel* sync_note_label = - new QLabel(tr("Note: Weeaboo is unable to synchronize multiple services at the same time."), sync_group_box); + new QLabel(tr("Note: Minori is unable to synchronize multiple services at the same time."), sync_group_box); QVBoxLayout* sync_layout = new QVBoxLayout; sync_layout->addWidget(sync_combo_box_label);
--- a/src/gui/pages/anime_list.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/gui/pages/anime_list.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -193,8 +193,8 @@ void AnimeListWidgetModel::UpdateAnime(int id) { /* meh... it might be better to just reinit the entire list */ int i = 0; - for (const auto& [a_id, anime] : Anime::db.items) { - if (anime.IsInUserList() && a_id == id && anime.GetUserStatus() == status) { + for (const auto& a : Anime::db.items) { + if (a.second.IsInUserList() && a.first == id && a.second.GetUserStatus() == status) { emit dataChanged(index(i), index(i)); } i++; @@ -210,9 +210,9 @@ if (has_children) beginResetModel(); list.clear(); - for (const auto& [id, anime] : Anime::db.items) { - if (anime.IsInUserList() && anime.GetUserStatus() == status) { - list.push_back(anime); + for (const auto& a : Anime::db.items) { + if (a.second.IsInUserList() && a.second.GetUserStatus() == status) { + list.push_back(a.second); } } if (has_children) endResetModel();
--- a/src/gui/pages/statistics.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/gui/pages/statistics.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -24,7 +24,7 @@ anime_list_data = anime_list_paragraph->GetParagraph(); UiUtils::LabelledTextParagraph* application_paragraph = - new UiUtils::LabelledTextParagraph("Weeaboo", "Uptime:", "", this); + new UiUtils::LabelledTextParagraph("Minori", "Uptime:", "", this); application_data = application_paragraph->GetParagraph(); layout()->addWidget(anime_list_paragraph);
--- a/src/gui/sidebar.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/gui/sidebar.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -61,12 +61,10 @@ return !(index.isValid() && index.flags() & Qt::ItemIsEnabled); } -QItemSelectionModel::SelectionFlags SideBar::selectionCommand(const QModelIndex& index, const QEvent* event) const { +QItemSelectionModel::SelectionFlags SideBar::selectionCommand(const QModelIndex& index, const QEvent*) const { if (IndexIsSeparator(index)) return QItemSelectionModel::NoUpdate; return QItemSelectionModel::ClearAndSelect; - /* silence unused parameter warnings */ - (void)event; } void SideBar::mouseMoveEvent(QMouseEvent* event) {
--- a/src/main.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/main.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -12,7 +12,7 @@ MainWindow window; window.resize(941, 750); - window.setWindowTitle("Weeaboo"); + window.setWindowTitle("Minori"); window.show(); return app.exec();
--- a/src/services/anilist.cpp Sat Sep 16 02:06:01 2023 -0400 +++ b/src/services/anilist.cpp Sun Sep 17 06:14:30 2023 -0400 @@ -16,6 +16,8 @@ #include <format> #define CLIENT_ID "13706" +using nlohmann::literals::operator "" _json_pointer; + namespace Services::AniList { class Account { @@ -119,17 +121,17 @@ Date ParseDate(const nlohmann::json& json) { Date date; - if (json.contains("/year"_json_pointer) && json["/year"_json_pointer].is_number()) + if (json.contains("/year"_json_pointer) && json.at("/year"_json_pointer).is_number()) date.SetYear(JSON::GetInt(json, "/year"_json_pointer)); else date.VoidYear(); - if (json.contains("/month"_json_pointer) && json["/month"_json_pointer].is_number()) + if (json.contains("/month"_json_pointer) && json.at("/month"_json_pointer).is_number()) date.SetMonth(JSON::GetInt(json, "/month"_json_pointer)); else date.VoidMonth(); - if (json.contains("/day"_json_pointer) && json["/day"_json_pointer].is_number()) + if (json.contains("/day"_json_pointer) && json.at("/day"_json_pointer).is_number()) date.SetDay(JSON::GetInt(json, "/day"_json_pointer)); else date.VoidDay(); @@ -149,7 +151,7 @@ Anime::Anime& anime = Anime::db.items[id]; anime.SetId(id); - ParseTitle(json["/title"_json_pointer], anime); + ParseTitle(json.at("/title"_json_pointer), anime); anime.SetEpisodes(JSON::GetInt(json, "/episodes"_json_pointer)); anime.SetFormat(AniListStringToAnimeFormatMap[JSON::GetString(json, "/format"_json_pointer)]);