Mercurial > minori
changeset 369:47c9f8502269
*: clang-format all the things
I've edited the formatting a bit. Now pointer asterisks (and reference
ampersands) are on the variable instead of the type, as well as having
newlines for function braces (but nothing else)
line wrap: on
line diff
--- a/.clang-format Fri Jul 25 10:05:23 2025 -0400 +++ b/.clang-format Fri Jul 25 10:16:02 2025 -0400 @@ -1,10 +1,11 @@ --- BasedOnStyle: LLVM UseTab: ForIndentation -PointerAlignment: Left +PointerAlignment: Right ColumnLimit: 120 IndentWidth: 4 TabWidth: 4 +PPIndentWidth: 1 # hack!!! AccessModifierOffset: -4 @@ -13,7 +14,7 @@ IndentAccessModifiers: false IndentPPDirectives: AfterHash -BreakBeforeBraces: Attach +BreakBeforeBraces: WebKit BreakStringLiterals: true AlwaysBreakTemplateDeclarations: true
--- a/include/core/anime.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/anime.h Fri Jul 25 10:16:02 2025 -0400 @@ -6,8 +6,8 @@ #include <array> #include <map> +#include <optional> #include <vector> -#include <optional> namespace Anime { @@ -17,12 +17,11 @@ Completed, Paused, Dropped, - Planning + Planning, }; constexpr std::array<ListStatus, 5> ListStatuses{ - ListStatus::Current, ListStatus::Completed, ListStatus::Paused, - ListStatus::Dropped, ListStatus::Planning + ListStatus::Current, ListStatus::Completed, ListStatus::Paused, ListStatus::Dropped, ListStatus::Planning, }; enum class SeriesStatus { @@ -31,16 +30,12 @@ Releasing, NotYetReleased, Cancelled, - Hiatus + Hiatus, }; constexpr std::array<SeriesStatus, 6> SeriesStatuses{ - SeriesStatus::Unknown, - SeriesStatus::Finished, - SeriesStatus::Releasing, - SeriesStatus::NotYetReleased, - SeriesStatus::Cancelled, - SeriesStatus::Hiatus + SeriesStatus::Unknown, SeriesStatus::Finished, SeriesStatus::Releasing, + SeriesStatus::NotYetReleased, SeriesStatus::Cancelled, SeriesStatus::Hiatus, }; enum class SeriesFormat { @@ -51,41 +46,39 @@ Special, Ova, Ona, - Music + Music, }; constexpr std::array<SeriesFormat, 8> SeriesFormats{ - SeriesFormat::Unknown, - SeriesFormat::Tv, - SeriesFormat::TvShort, - SeriesFormat::Movie, - SeriesFormat::Special, - SeriesFormat::Ova, - SeriesFormat::Ona, - SeriesFormat::Music + SeriesFormat::Unknown, SeriesFormat::Tv, SeriesFormat::TvShort, SeriesFormat::Movie, + SeriesFormat::Special, SeriesFormat::Ova, SeriesFormat::Ona, SeriesFormat::Music, }; enum class TitleLanguage { Romaji, Native, - English + English, }; -constexpr std::array<TitleLanguage, 3> TitleLanguages{TitleLanguage::Romaji, TitleLanguage::Native, TitleLanguage::English}; +constexpr std::array<TitleLanguage, 3> TitleLanguages{ + TitleLanguage::Romaji, + TitleLanguage::Native, + TitleLanguage::English, +}; enum class Service { None, AniList, MyAnimeList, - Kitsu + Kitsu, }; /* this doesn't include MAL and Kitsu because they aren't really * "valid" services yet. */ constexpr std::array<Service, 3> Services{ - Service::AniList, - Service::MyAnimeList, - Service::Kitsu + Service::AniList, + Service::MyAnimeList, + Service::Kitsu, }; enum class ScoreFormat { @@ -93,11 +86,12 @@ Point10Decimal, // 0.0-10.0 Point10, // 0-10 Point5, // 0-5, should be represented in stars - Point3 // 1-3, should be represented in smileys + Point3, // 1-3, should be represented in smileys }; -constexpr std::array<ScoreFormat, 5> ScoreFormats{ScoreFormat::Point100, ScoreFormat::Point10Decimal, - ScoreFormat::Point10, ScoreFormat::Point5, ScoreFormat::Point3}; +constexpr std::array<ScoreFormat, 5> ScoreFormats{ + ScoreFormat::Point100, ScoreFormat::Point10Decimal, ScoreFormat::Point10, ScoreFormat::Point5, ScoreFormat::Point3, +}; struct ListInformation { std::string id; @@ -147,17 +141,17 @@ uint64_t GetUserTimeUpdated() const; std::string GetUserNotes() const; - void SetUserId(const std::string& id); + void SetUserId(const std::string &id); void SetUserStatus(ListStatus status); void SetUserScore(int score); void SetUserProgress(int progress); - void SetUserDateStarted(const Date& started); - void SetUserDateCompleted(const Date& completed); + void SetUserDateStarted(const Date &started); + void SetUserDateCompleted(const Date &completed); void SetUserIsPrivate(bool is_private); void SetUserRewatchedTimes(int rewatched); void SetUserIsRewatching(bool rewatching); void SetUserTimeUpdated(uint64_t updated); - void SetUserNotes(const std::string& notes); + void SetUserNotes(const std::string ¬es); /* Series data */ int GetId() const; @@ -179,16 +173,16 @@ std::optional<std::string> GetServiceUrl(Service service) const; void SetId(int id); - void SetServiceId(Service service, const std::string& id); - void SetTitle(TitleLanguage language, const std::string& title); - void SetTitleSynonyms(const std::vector<std::string>& synonyms); - void AddTitleSynonym(const std::string& synonym); + void SetServiceId(Service service, const std::string &id); + void SetTitle(TitleLanguage language, const std::string &title); + void SetTitleSynonyms(const std::vector<std::string> &synonyms); + void AddTitleSynonym(const std::string &synonym); void SetEpisodes(int episodes); void SetAiringStatus(SeriesStatus status); - void SetStartedDate(const Date& date); - void SetCompletedDate(const Date& date); - void SetGenres(const std::vector<std::string>& genres); - void SetProducers(const std::vector<std::string>& producers); + void SetStartedDate(const Date &date); + void SetCompletedDate(const Date &date); + void SetGenres(const std::vector<std::string> &genres); + void SetProducers(const std::vector<std::string> &producers); void SetFormat(SeriesFormat format); void SetAudienceScore(double audience_score); void SetSynopsis(std::string synopsis);
--- a/include/core/anime_db.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/anime_db.h Fri Jul 25 10:16:02 2025 -0400 @@ -18,19 +18,19 @@ double GetAverageScore() const; double GetScoreDeviation() const; size_t GetListsAnimeAmount(ListStatus status) const; - int LookupAnimeTitle(const std::string& title) const; + int LookupAnimeTitle(const std::string &title) const; - bool GetDatabaseAsJSON(nlohmann::json& json) const; + bool GetDatabaseAsJSON(nlohmann::json &json) const; bool SaveDatabaseToDisk() const; - bool ParseDatabaseJSON(const nlohmann::json& json); + bool ParseDatabaseJSON(const nlohmann::json &json); bool LoadDatabaseFromDisk(); /* These are here to make sure that our service IDs don't collide * and make the whole thing go boom. */ int GetUnusedId() const; - int LookupServiceId(Service service, const std::string& id_to_find) const; - int LookupServiceIdOrUnused(Service service, const std::string& id_to_find) const; + int LookupServiceId(Service service, const std::string &id_to_find) const; + int LookupServiceIdOrUnused(Service service, const std::string &id_to_find) const; /* when syncing we don't want to keep deleted anime */ void RemoveAllUserData();
--- a/include/core/anime_season.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/anime_season.h Fri Jul 25 10:16:02 2025 -0400 @@ -18,26 +18,26 @@ }; static constexpr std::array<Name, 4> Names{ - Name::Winter, - Name::Spring, - Name::Summer, - Name::Autumn + Name::Winter, + Name::Spring, + Name::Summer, + Name::Autumn, }; Season() = default; Season(Name s, Date::Year y); - explicit Season(const Date& date); + explicit Season(const Date &date); - bool operator==(const Season& o) const; - bool operator!=(const Season& o) const; + bool operator==(const Season &o) const; + bool operator!=(const Season &o) const; - bool operator<(const Season& o) const; - bool operator>(const Season& o) const; - bool operator<=(const Season& o) const; - bool operator>=(const Season& o) const; + bool operator<(const Season &o) const; + bool operator>(const Season &o) const; + bool operator<=(const Season &o) const; + bool operator>=(const Season &o) const; - Season& operator++(); - Season& operator--(); + Season &operator++(); + Season &operator--(); Name season = Name::Unknown; Date::Year year = 0;
--- a/include/core/bit_cast.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/bit_cast.h Fri Jul 25 10:16:02 2025 -0400 @@ -3,15 +3,16 @@ /* XXX need to move more "core" stuff into the minori namespace */ -#include <type_traits> +#include <cstring> #include <memory> -#include <cstring> +#include <type_traits> namespace minori { /* C++17 doesn't have this unfortunately */ template<typename To, class From> -To BitCast(From from) { +To BitCast(From from) +{ static_assert(sizeof(From) == sizeof(To), "Types must match sizes"); static_assert(std::is_pod<From>::value, "Requires POD input"); static_assert(std::is_pod<To>::value, "Requires POD output"); @@ -21,6 +22,6 @@ return to; } -} +} // namespace minori #endif /* MINORI_CORE_BIT_CAST_H_ */
--- a/include/core/byte_stream.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/byte_stream.h Fri Jul 25 10:16:02 2025 -0400 @@ -3,10 +3,11 @@ #include "core/endian.h" +#include <cstdint> +#include <cstdlib> #include <string> +#include <type_traits> #include <vector> -#include <cstdint> -#include <type_traits> struct ByteStream { public: @@ -21,17 +22,19 @@ void SetEndianness(ByteOrder endian); template<typename T> - bool ReadBinary(T& ret) { + bool ReadBinary(T &ret) + { if (offset_ + sizeof(T) >= size_) return false; - ret = *reinterpret_cast<T*>(bytes_ + offset_); + std::memcpy(&ret, bytes_ + offset_, sizeof(ret)); Advance(sizeof(T)); return true; } template<typename T> - bool ReadInt(T& ret) { + bool ReadInt(T &ret) + { static_assert(std::is_integral<T>::value); if (!ReadBinary<T>(ret)) @@ -60,7 +63,7 @@ return true; } - bool ReadString(std::string& str, std::size_t size); + bool ReadString(std::string &str, std::size_t size); bool Advance(std::size_t amount); private:
--- a/include/core/date.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/date.h Fri Jul 25 10:16:02 2025 -0400 @@ -36,9 +36,9 @@ Date(); Date(Year y); Date(Year y, Month m, Day d); - Date(const std::string& str); - Date(const QDate& date); - Date(const nlohmann::json& json); + Date(const std::string &str); + Date(const QDate &date); + Date(const nlohmann::json &json); Date(Time::Timestamp timestamp); bool IsValid() const;
--- a/include/core/endian.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/endian.h Fri Jul 25 10:16:02 2025 -0400 @@ -12,66 +12,56 @@ private: /* check for compiler builtins for byteswapping */ #ifdef __has_builtin -# if __has_builtin(__builtin_bswap16) -# define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x) -# endif -# if __has_builtin(__builtin_bswap32) -# define COMPILER_BUILTIN_BSWAP32(x) __builtin_bswap32(x) -# endif -# if __has_builtin(__builtin_bswap64) -# define COMPILER_BUILTIN_BSWAP64(x) __builtin_bswap64(x) -# endif +# if __has_builtin(__builtin_bswap16) +# define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x) +# endif +# if __has_builtin(__builtin_bswap32) +# define COMPILER_BUILTIN_BSWAP32(x) __builtin_bswap32(x) +# endif +# if __has_builtin(__builtin_bswap64) +# define COMPILER_BUILTIN_BSWAP64(x) __builtin_bswap64(x) +# endif #endif - static constexpr uint16_t byteswap_16(uint16_t x) { + static constexpr uint16_t byteswap_16(uint16_t x) + { #ifdef COMPILER_BUILTIN_BSWAP16 return COMPILER_BUILTIN_BSWAP16(x); #else - return ( - ((x & UINT16_C(0x00FF)) << 8) - | ((x & UINT16_C(0xFF00)) >> 8) - ); + return (((x & UINT16_C(0x00FF)) << 8) | ((x & UINT16_C(0xFF00)) >> 8)); #endif } - static constexpr uint32_t byteswap_32(uint32_t x) { + static constexpr uint32_t byteswap_32(uint32_t x) + { #ifdef COMPILER_BUILTIN_BSWAP32 return COMPILER_BUILTIN_BSWAP32(x); #else - return ( - ((x & UINT32_C(0x000000FF)) << 24) - | ((x & UINT32_C(0x0000FF00)) << 8) - | ((x & UINT32_C(0x00FF0000)) >> 8) - | ((x & UINT32_C(0xFF000000)) >> 24) - ); + return (((x & UINT32_C(0x000000FF)) << 24) | ((x & UINT32_C(0x0000FF00)) << 8) | + ((x & UINT32_C(0x00FF0000)) >> 8) | ((x & UINT32_C(0xFF000000)) >> 24)); #endif } - static constexpr uint64_t byteswap_64(uint64_t x) { + static constexpr uint64_t byteswap_64(uint64_t x) + { #ifdef COMPILER_BUILTIN_BSWAP64 return COMPILER_BUILTIN_BSWAP64(x); #else - return ( - ((x & UINT64_C(0x00000000000000FF)) << 56) - | ((x & UINT64_C(0x000000000000FF00)) << 40) - | ((x & UINT64_C(0x0000000000FF0000)) << 24) - | ((x & UINT64_C(0x00000000FF000000)) << 8) - | ((x & UINT64_C(0x000000FF00000000)) >> 8) - | ((x & UINT64_C(0x0000FF0000000000)) >> 24) - | ((x & UINT64_C(0x00FF000000000000)) >> 40) - | ((x & UINT64_C(0xFF00000000000000)) >> 56) - ); + return (((x & UINT64_C(0x00000000000000FF)) << 56) | ((x & UINT64_C(0x000000000000FF00)) << 40) | + ((x & UINT64_C(0x0000000000FF0000)) << 24) | ((x & UINT64_C(0x00000000FF000000)) << 8) | + ((x & UINT64_C(0x000000FF00000000)) >> 8) | ((x & UINT64_C(0x0000FF0000000000)) >> 24) | + ((x & UINT64_C(0x00FF000000000000)) >> 40) | ((x & UINT64_C(0xFF00000000000000)) >> 56)); #endif } #ifdef COMPILER_BUILTIN_BSWAP16 -# undef COMPILER_BUILTIN_BSWAP16 +# undef COMPILER_BUILTIN_BSWAP16 #endif #ifdef COMPILER_BUILTIN_BSWAP32 -# undef COMPILER_BUILTIN_BSWAP32 +# undef COMPILER_BUILTIN_BSWAP32 #endif #ifdef COMPILER_BUILTIN_BSWAP64 -# undef COMPILER_BUILTIN_BSWAP64 +# undef COMPILER_BUILTIN_BSWAP64 #endif public: #if defined(BYTE_ORDER_BIG) @@ -81,11 +71,12 @@ static constexpr bool big = false; static constexpr bool little = true; #else -#error "unsupported endianness" +# error "unsupported endianness" #endif template<typename T> - static constexpr T byteswap(T x) { + static constexpr T byteswap(T x) + { static_assert(std::is_integral<T>::value); static_assert(std::is_unsigned<T>::value, "use signed_byteswap"); @@ -104,7 +95,8 @@ /* this can't be constexpr */ template<typename T> - static T signed_byteswap(T x) { + static T signed_byteswap(T x) + { static_assert(std::is_integral<T>::value); static_assert(std::is_signed<T>::value, "use regular byteswap"); @@ -113,7 +105,8 @@ } template<typename T> - static constexpr T byteswap_little_to_host(T x) { + static constexpr T byteswap_little_to_host(T x) + { if constexpr (little) { return x; } else if constexpr (big) { @@ -122,7 +115,8 @@ } template<typename T> - static constexpr T byteswap_big_to_host(T x) { + static constexpr T byteswap_big_to_host(T x) + { if constexpr (big) { return x; } else if constexpr (little) { @@ -131,7 +125,8 @@ } template<typename T> - static T signed_byteswap_little_to_host(T x) { + static T signed_byteswap_little_to_host(T x) + { if constexpr (little) { return x; } else if constexpr (big) { @@ -140,13 +135,15 @@ } template<typename T> - static T signed_byteswap_big_to_host(T x) { + static T signed_byteswap_big_to_host(T x) + { if constexpr (big) { return x; } else if constexpr (little) { return signed_byteswap(x); } } + private: Endian() = delete; };
--- a/include/core/filesystem.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/filesystem.h Fri Jul 25 10:16:02 2025 -0400 @@ -5,7 +5,7 @@ namespace Filesystem { -void CreateDirectories(const std::filesystem::path& path); +void CreateDirectories(const std::filesystem::path &path); std::filesystem::path GetDotPath(); // %APPDATA%/minori/, ~/Library/Application Support/minori/, ~/.config/minori/... std::filesystem::path GetConfigPath(); // (dotpath)/config.json std::filesystem::path GetAnimeDBPath(); // (dotpath)/anime/db.json
--- a/include/core/http.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/http.h Fri Jul 25 10:16:02 2025 -0400 @@ -4,47 +4,48 @@ #include <QByteArray> #include <QThread> +#include <mutex> #include <string> #include <vector> -#include <mutex> namespace HTTP { /* calls libcurl to encode/decode */ -std::string UrlEncode(const std::string& data); -std::string UrlDecode(const std::string& data); +std::string UrlEncode(const std::string &data); +std::string UrlDecode(const std::string &data); -std::string EncodeParamsList(std::string base, const std::map<std::string, std::string>& params); +std::string EncodeParamsList(std::string base, const std::map<std::string, std::string> ¶ms); enum class Type { Get, Post }; -QByteArray Request(const std::string& url, const std::vector<std::string>& headers = {}, const std::string& data = "", Type type = Type::Get); +QByteArray Request(const std::string &url, const std::vector<std::string> &headers = {}, const std::string &data = "", + Type type = Type::Get); class RequestThread final : public QThread { Q_OBJECT public: - RequestThread(Type type = Type::Get, QObject* parent = nullptr); - RequestThread(const std::string& url, const std::vector<std::string>& headers = {}, - const std::string& data = "", Type type = Type::Get, QObject* parent = nullptr); + RequestThread(Type type = Type::Get, QObject *parent = nullptr); + RequestThread(const std::string &url, const std::vector<std::string> &headers = {}, const std::string &data = "", + Type type = Type::Get, QObject *parent = nullptr); ~RequestThread(); - void SetUrl(const std::string& url); - void SetHeaders(const std::vector<std::string>& headers); - void SetData(const std::string& data); + void SetUrl(const std::string &url); + void SetHeaders(const std::vector<std::string> &headers); + void SetData(const std::string &data); void SetType(Type type); void Stop(); signals: - void ReceivedData(const QByteArray& ba); + void ReceivedData(const QByteArray &ba); protected: void run() override; - static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata); + static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata); std::string url_; std::string data_;
--- a/include/core/json.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/json.h Fri Jul 25 10:16:02 2025 -0400 @@ -7,8 +7,10 @@ namespace nlohmann { +/* hack to get std::optional working */ template<typename T> -void to_json(nlohmann::json& j, const std::optional<T>& v) { +void to_json(nlohmann::json &j, const std::optional<T> &v) +{ if (v.has_value()) j = v.value(); else @@ -16,7 +18,8 @@ } template<typename T> -void from_json(const nlohmann::json& j, std::optional<T>& v) { +void from_json(const nlohmann::json &j, std::optional<T> &v) +{ v = j.is_null() ? std::nullopt : j.get<T>(); } @@ -25,7 +28,8 @@ namespace JSON { template<typename T = std::string> -T GetString(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, T def) { +T GetString(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr, T def) +{ if (json.contains(ptr) && json[ptr].is_string()) return json[ptr].get<T>(); else @@ -33,7 +37,8 @@ } template<typename T = int> -T GetNumber(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, T def = 0) { +T GetNumber(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr, T def = 0) +{ if (json.contains(ptr) && json[ptr].is_number()) return json[ptr].get<T>(); else @@ -41,15 +46,16 @@ } template<typename T = std::vector<std::string>> -T GetArray(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, T def = 0) { +T GetArray(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr, T def = 0) +{ if (json.contains(ptr) && json[ptr].is_array()) return json[ptr].get<T>(); else return def; } -nlohmann::json GetValue(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr); -bool GetBoolean(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, bool def = false); +nlohmann::json GetValue(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr); +bool GetBoolean(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr, bool def = false); } // namespace JSON
--- a/include/core/session.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/session.h Fri Jul 25 10:16:02 2025 -0400 @@ -1,18 +1,19 @@ #ifndef MINORI_CORE_SESSION_H_ #define MINORI_CORE_SESSION_H_ +#include "core/config.h" #include "core/time.h" -#include "core/config.h" #include "gui/locale.h" +#include <QElapsedTimer> #include <QObject> -#include <QElapsedTimer> #include "semver/semver.hpp" #include <atomic> +#include <random> #include <string> -#include <random> +#include <cstdint> class MainWindow; @@ -22,13 +23,13 @@ public: Session(); - void SetMainWindow(MainWindow* window); + void SetMainWindow(MainWindow *window); - void SetStatusBar(const std::string& message); + void SetStatusBar(const std::string &message); /* we literally *cannot* be lying to the user by doing this */ void IncrementRequests(); - unsigned int GetRequests(); + std::uint32_t GetRequests(); int uptime(); Config config; @@ -36,19 +37,19 @@ std::mt19937 gen; static constexpr semver::version version{ - MINORI_VERSION_MAJOR, - MINORI_VERSION_MINOR, - MINORI_VERSION_PATCH, + MINORI_VERSION_MAJOR, + MINORI_VERSION_MINOR, + MINORI_VERSION_PATCH, }; signals: - void StatusBarChange(const std::string& message); + void StatusBarChange(const std::string &message); private: /* IncrementRequests() gets called by different threads */ - std::atomic<unsigned int> requests_ = 0; + std::atomic<std::uint32_t> requests_ = 0; QElapsedTimer timer_; - MainWindow* window_; + MainWindow *window_; }; extern Session session;
--- a/include/core/strings.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/strings.h Fri Jul 25 10:16:02 2025 -0400 @@ -16,63 +16,65 @@ /* Implode function: takes a vector of strings and turns it * into a string, separated by delimiters. */ -std::string Implode(const std::vector<std::string>& vector, const std::string& delimiter); -std::vector<std::string> Split(const std::string& text, const std::string& delimiter); +std::string Implode(const std::vector<std::string> &vector, const std::string &delimiter); +std::vector<std::string> Split(const std::string &text, const std::string &delimiter); /* Substring removal functions */ -void ReplaceAll(std::string& string, std::string_view find, std::string_view replace); -void NormalizeUnicode(std::string& string); -void NormalizeAnimeTitle(std::string& string); +void ReplaceAll(std::string &string, std::string_view find, std::string_view replace); +void NormalizeUnicode(std::string &string); +void NormalizeAnimeTitle(std::string &string); /* stupid HTML bullshit */ -void TextifySynopsis(std::string& string); +void TextifySynopsis(std::string &string); -std::string ToUpper(const std::string& string); -std::string ToLower(const std::string& string); +std::string ToUpper(const std::string &string); +std::string ToLower(const std::string &string); /* functions that make the way we convert from and to * different string formats universal (and these functions * typically do things the right way so we avoid retarded * code) */ -std::wstring ToWstring(const std::string& string); -std::wstring ToWstring(const QString& string); -std::string ToUtf8String(const std::wstring& wstring); -std::string ToUtf8String(const QString& string); -std::string ToUtf8String(const QByteArray& ba); -std::string ToUtf8String(const std::u32string& u32string); -std::u32string ToUcs4String(const std::string& string); -QString ToQString(const std::string& string); -QString ToQString(const std::wstring& wstring); +std::wstring ToWstring(const std::string &string); +std::wstring ToWstring(const QString &string); +std::string ToUtf8String(const std::wstring &wstring); +std::string ToUtf8String(const QString &string); +std::string ToUtf8String(const QByteArray &ba); +std::string ToUtf8String(const std::u32string &u32string); +std::u32string ToUcs4String(const std::string &string); +QString ToQString(const std::string &string); +QString ToQString(const std::wstring &wstring); /* not really an "int"... but who cares? */ template<typename T = int, std::enable_if_t<std::is_arithmetic<T>::value, bool> = true> -T ToInt(const std::string& str, T def = 0) { +T ToInt(const std::string &str, T def = 0) +{ std::istringstream s(str); s >> std::noboolalpha >> def; return def; } template<typename T, std::enable_if_t<std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, bool> = true> -std::string ToUtf8String(T i) { +std::string ToUtf8String(T i) +{ std::ostringstream s; s << std::noboolalpha << i; return s.str(); } -bool ToBool(const std::string& s, bool def); +bool ToBool(const std::string &s, bool def); std::string ToUtf8String(bool b); -uint64_t HumanReadableSizeToBytes(const std::string& str); +uint64_t HumanReadableSizeToBytes(const std::string &str); std::string BytesToHumanReadableSize(uint64_t bytes, int precision = 2); -void RemoveLeadingChars(std::string& s, const char c); -void RemoveTrailingChars(std::string& s, const char c); +void RemoveLeadingChars(std::string &s, const char c); +void RemoveTrailingChars(std::string &s, const char c); -bool BeginningMatchesSubstring(const std::string& str, const std::string& sub); +bool BeginningMatchesSubstring(const std::string &str, const std::string &sub); -std::string Translate(const char* str); +std::string Translate(const char *str); }; // namespace Strings
--- a/include/core/time.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/time.h Fri Jul 25 10:16:02 2025 -0400 @@ -19,7 +19,7 @@ /* in UTC */ Timestamp GetSystemTime(); -Timestamp ParseISO8601Time(const std::string& str); +Timestamp ParseISO8601Time(const std::string &str); }; // namespace Time
--- a/include/core/torrent.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/core/torrent.h Fri Jul 25 10:16:02 2025 -0400 @@ -26,20 +26,20 @@ std::string GetGuid() const { return _guid; }; QDateTime GetDate() const { return _date; }; - void SetTitle(const std::string& title) { _title = title; }; - void SetCategory(const std::string& category) { _category = category; }; - void SetEpisode(const std::string& episode) { _episode = episode; }; - void SetGroup(const std::string& group) { _group = group; }; + void SetTitle(const std::string &title) { _title = title; }; + void SetCategory(const std::string &category) { _category = category; }; + void SetEpisode(const std::string &episode) { _episode = episode; }; + void SetGroup(const std::string &group) { _group = group; }; void SetSize(const size_t size) { _size = size; }; - void SetResolution(const std::string& resolution) { _resolution = resolution; }; + void SetResolution(const std::string &resolution) { _resolution = resolution; }; void SetSeeders(const int seeders) { _seeders = seeders; }; void SetLeechers(const int leechers) { _leechers = leechers; }; void SetDownloads(const int downloads) { _downloads = downloads; }; - void SetDescription(const std::string& description) { _description = description; }; - void SetFilename(const std::string& filename) { _filename = filename; }; - void SetLink(const std::string& link) { _link = link; }; - void SetGuid(const std::string& guid) { _guid = guid; }; - void SetDate(const QDateTime& date) { _date = date; }; + void SetDescription(const std::string &description) { _description = description; }; + void SetFilename(const std::string &filename) { _filename = filename; }; + void SetLink(const std::string &link) { _link = link; }; + void SetGuid(const std::string &guid) { _guid = guid; }; + void SetDate(const QDateTime &date) { _date = date; }; private: std::string _title;
--- a/include/gui/locale.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/gui/locale.h Fri Jul 25 10:16:02 2025 -0400 @@ -9,20 +9,20 @@ namespace Locale { -std::string GetLocaleFullName(const QLocale& locale); +std::string GetLocaleFullName(const QLocale &locale); class Locale { public: Locale(); - Locale(const std::string& name); + Locale(const std::string &name); QLocale GetLocale() const; std::vector<QLocale> GetAvailableLocales() const; void RefreshAvailableLocales(); // why would this ever be called? - bool IsLocaleAvailable(const QLocale& locale) const; - bool SetActiveLocale(const QLocale& locale); + bool IsLocaleAvailable(const QLocale &locale) const; + bool SetActiveLocale(const QLocale &locale); private: - bool SwitchTranslator(QTranslator& translator, const QString& name); + bool SwitchTranslator(QTranslator &translator, const QString &name); QTranslator _translator; QTranslator _translator_qt;
--- a/include/gui/theme.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/gui/theme.h Fri Jul 25 10:16:02 2025 -0400 @@ -11,11 +11,7 @@ Dark }; -constexpr std::array<Theme, 3> Themes{ - Theme::Default, - Theme::Light, - Theme::Dark -}; +constexpr std::array<Theme, 3> Themes{Theme::Default, Theme::Light, Theme::Dark}; class ThemeManager final { public:
--- a/include/gui/window.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/gui/window.h Fri Jul 25 10:16:02 2025 -0400 @@ -13,8 +13,8 @@ #include "gui/pages/statistics.h" #include "gui/pages/torrents.h" +#include <QCloseEvent> #include <QMainWindow> -#include <QCloseEvent> #include <QStackedWidget> #include <QThread> #include <QTimer> @@ -33,29 +33,29 @@ Q_OBJECT public: - MainWindowPlayingThread(QObject* object = nullptr) : QThread(object) {} + MainWindowPlayingThread(QObject *object = nullptr) : QThread(object) {} protected: void run() override; signals: - void Done(const std::vector<std::string>& files); + void Done(const std::vector<std::string> &files); }; class MainWindowAsyncSynchronizeThread final : public QThread { Q_OBJECT public: - MainWindowAsyncSynchronizeThread(QAction* action, AnimeListPage* page, QObject* object = nullptr); - void SetAction(QAction* action); - void SetPage(AnimeListPage* page); + MainWindowAsyncSynchronizeThread(QAction *action, AnimeListPage *page, QObject *object = nullptr); + void SetAction(QAction *action); + void SetPage(AnimeListPage *page); protected: void run() override; private: - QAction* action_ = nullptr; - AnimeListPage* page_ = nullptr; + QAction *action_ = nullptr; + AnimeListPage *page_ = nullptr; }; class MainWindow final : public QMainWindow { @@ -74,19 +74,19 @@ TORRENTS }; - MainWindow(QWidget* parent = nullptr); - void SetActivePage(QWidget* page); + MainWindow(QWidget *parent = nullptr); + void SetActivePage(QWidget *page); void CreateBars(); void AddMainWidgets(); void RetranslateUI(); void UpdateFolderMenu(); - void AsyncSynchronize(QAction* action, QStackedWidget* stack); - void changeEvent(QEvent* event) override; - void showEvent(QShowEvent* event) override; - void closeEvent(QCloseEvent* event) override; + void AsyncSynchronize(QAction *action, QStackedWidget *stack); + void changeEvent(QEvent *event) override; + void showEvent(QShowEvent *event) override; + void closeEvent(QCloseEvent *event) override; public slots: - void SetStatusMessage(const std::string& message); + void SetStatusMessage(const std::string &message); private: QWidget main_widget_; @@ -106,7 +106,7 @@ MainWindowAsyncSynchronizeThread async_synchronize_thread_; - QMenu* folder_menu = nullptr; + QMenu *folder_menu = nullptr; }; #endif // MINORI_WINDOW_H_
--- a/include/library/library.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/library/library.h Fri Jul 25 10:16:02 2025 -0400 @@ -3,8 +3,8 @@ #include "library/library.h" +#include <filesystem> #include <optional> -#include <filesystem> #include <unordered_map> namespace Library {
--- a/include/services/anilist.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/services/anilist.h Fri Jul 25 10:16:02 2025 -0400 @@ -16,7 +16,7 @@ int GetAnimeList(); /* Search query */ -std::vector<int> Search(const std::string& search); +std::vector<int> Search(const std::string &search); bool GetSeason(Anime::Season season); /* Write queries (mutations) */
--- a/include/services/kitsu.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/services/kitsu.h Fri Jul 25 10:16:02 2025 -0400 @@ -11,12 +11,12 @@ namespace Kitsu { /* neither of these are stored in the config and only held temporarily */ -bool AuthorizeUser(const std::string& email, const std::string& password); +bool AuthorizeUser(const std::string &email, const std::string &password); bool RetrieveAnimeMetadata(int id); int GetAnimeList(); -std::vector<int> Search(const std::string& search); +std::vector<int> Search(const std::string &search); bool GetSeason(Anime::Season season); int UpdateAnimeEntry(int id);
--- a/include/services/services.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/services/services.h Fri Jul 25 10:16:02 2025 -0400 @@ -16,7 +16,7 @@ * no metadata to be retrieved */ bool RetrieveAnimeMetadata(int id); -std::vector<int> Search(const std::string& search); +std::vector<int> Search(const std::string &search); bool GetSeason(Anime::Season season); void UpdateAnimeEntry(int id);
--- a/include/track/media.h Fri Jul 25 10:05:23 2025 -0400 +++ b/include/track/media.h Fri Jul 25 10:16:02 2025 -0400 @@ -7,7 +7,7 @@ namespace Track { namespace Media { -bool GetCurrentlyPlaying(std::vector<std::string>& vec); +bool GetCurrentlyPlaying(std::vector<std::string> &vec); } // namespace Media } // namespace Track
--- a/src/core/anime.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/anime.cc Fri Jul 25 10:16:02 2025 -0400 @@ -9,51 +9,59 @@ #include "core/strings.h" #include <algorithm> +#include <cassert> #include <string> #include <vector> -#include <cassert> #include <iostream> namespace Anime { /* User list data */ -bool Anime::IsInUserList() const { +bool Anime::IsInUserList() const +{ if (list_info_.has_value()) return true; return false; } -void Anime::AddToUserList() { +void Anime::AddToUserList() +{ ListInformation list; list_info_.emplace(list); } -void Anime::RemoveFromUserList() { +void Anime::RemoveFromUserList() +{ list_info_.reset(); } -std::string Anime::GetUserId() const { +std::string Anime::GetUserId() const +{ assert(list_info_.has_value()); return list_info_->id; } -ListStatus Anime::GetUserStatus() const { +ListStatus Anime::GetUserStatus() const +{ assert(list_info_.has_value()); return list_info_->status; } -int Anime::GetUserProgress() const { +int Anime::GetUserProgress() const +{ assert(list_info_.has_value()); return list_info_->progress; } -int Anime::GetUserScore() const { +int Anime::GetUserScore() const +{ assert(list_info_.has_value()); return list_info_->score; } -std::string Anime::GetUserPresentableScore() const { +std::string Anime::GetUserPresentableScore() const +{ assert(list_info_.has_value()); const int score = list_info_->score; @@ -87,102 +95,122 @@ } } -Date Anime::GetUserDateStarted() const { +Date Anime::GetUserDateStarted() const +{ assert(list_info_.has_value()); return list_info_->started; } -Date Anime::GetUserDateCompleted() const { +Date Anime::GetUserDateCompleted() const +{ assert(list_info_.has_value()); return list_info_->completed; } -bool Anime::GetUserIsPrivate() const { +bool Anime::GetUserIsPrivate() const +{ assert(list_info_.has_value()); return list_info_->is_private; } -unsigned int Anime::GetUserRewatchedTimes() const { +unsigned int Anime::GetUserRewatchedTimes() const +{ assert(list_info_.has_value()); return list_info_->rewatched_times; } -bool Anime::GetUserIsRewatching() const { +bool Anime::GetUserIsRewatching() const +{ assert(list_info_.has_value()); return list_info_->rewatching; } -uint64_t Anime::GetUserTimeUpdated() const { +uint64_t Anime::GetUserTimeUpdated() const +{ assert(list_info_.has_value()); return list_info_->updated; } -std::string Anime::GetUserNotes() const { +std::string Anime::GetUserNotes() const +{ assert(list_info_.has_value()); return list_info_->notes; } -void Anime::SetUserId(const std::string& id) { +void Anime::SetUserId(const std::string &id) +{ assert(list_info_.has_value()); list_info_->id = id; } -void Anime::SetUserStatus(ListStatus status) { +void Anime::SetUserStatus(ListStatus status) +{ assert(list_info_.has_value()); list_info_->status = status; } -void Anime::SetUserScore(int score) { +void Anime::SetUserScore(int score) +{ assert(list_info_.has_value()); list_info_->score = score; } -void Anime::SetUserProgress(int progress) { +void Anime::SetUserProgress(int progress) +{ assert(list_info_.has_value()); list_info_->progress = progress; } -void Anime::SetUserDateStarted(const Date& started) { +void Anime::SetUserDateStarted(const Date &started) +{ assert(list_info_.has_value()); list_info_->started = started; } -void Anime::SetUserDateCompleted(const Date& completed) { +void Anime::SetUserDateCompleted(const Date &completed) +{ assert(list_info_.has_value()); list_info_->completed = completed; } -void Anime::SetUserIsPrivate(bool is_private) { +void Anime::SetUserIsPrivate(bool is_private) +{ assert(list_info_.has_value()); list_info_->is_private = is_private; } -void Anime::SetUserRewatchedTimes(int rewatched) { +void Anime::SetUserRewatchedTimes(int rewatched) +{ assert(list_info_.has_value()); list_info_->rewatched_times = rewatched; } -void Anime::SetUserIsRewatching(bool rewatching) { +void Anime::SetUserIsRewatching(bool rewatching) +{ assert(list_info_.has_value()); list_info_->rewatching = rewatching; } -void Anime::SetUserTimeUpdated(uint64_t updated) { +void Anime::SetUserTimeUpdated(uint64_t updated) +{ assert(list_info_.has_value()); list_info_->updated = updated; } -void Anime::SetUserNotes(const std::string& notes) { +void Anime::SetUserNotes(const std::string ¬es) +{ assert(list_info_.has_value()); list_info_->notes = notes; } /* Series data */ -int Anime::GetId() const { +int Anime::GetId() const +{ return info_.id; } -std::optional<std::string> Anime::GetServiceId(Service service) const { +std::optional<std::string> Anime::GetServiceId(Service service) const +{ if (info_.ids.find(service) == info_.ids.end()) return std::nullopt; @@ -190,161 +218,192 @@ } /* note: this should use std::optional */ -std::optional<std::string> Anime::GetTitle(TitleLanguage language) const { +std::optional<std::string> Anime::GetTitle(TitleLanguage language) const +{ if (info_.titles.find(language) == info_.titles.end()) return std::nullopt; return info_.titles.at(language); } -std::vector<std::string> Anime::GetTitleSynonyms() const { +std::vector<std::string> Anime::GetTitleSynonyms() const +{ /* mainly for the GUI */ std::vector<std::string> result; - auto add_to_synonyms = [this](std::vector<std::string>& vec, std::string key) { + auto add_to_synonyms = [this](std::vector<std::string> &vec, std::string key) { if (!key.empty() && !std::count(vec.begin(), vec.end(), key) && key != GetUserPreferredTitle()) vec.push_back(key); }; - for (const auto& lang : TitleLanguages) + for (const auto &lang : TitleLanguages) if (info_.titles.find(lang) != info_.titles.end()) add_to_synonyms(result, info_.titles.at(lang)); - for (auto& synonym : info_.synonyms) + for (auto &synonym : info_.synonyms) add_to_synonyms(result, synonym); return result; } -int Anime::GetEpisodes() const { +int Anime::GetEpisodes() const +{ return info_.episodes; } -SeriesStatus Anime::GetAiringStatus() const { +SeriesStatus Anime::GetAiringStatus() const +{ return info_.status; } -Date Anime::GetStartedDate() const { +Date Anime::GetStartedDate() const +{ return info_.started; } -Date Anime::GetCompletedDate() const { +Date Anime::GetCompletedDate() const +{ return info_.completed; } -std::vector<std::string> Anime::GetGenres() const { +std::vector<std::string> Anime::GetGenres() const +{ return info_.genres; } -std::vector<std::string> Anime::GetProducers() const { +std::vector<std::string> Anime::GetProducers() const +{ return info_.producers; } -SeriesFormat Anime::GetFormat() const { +SeriesFormat Anime::GetFormat() const +{ return info_.format; } -Season Anime::GetSeason() const { +Season Anime::GetSeason() const +{ return Season(info_.started); } -double Anime::GetAudienceScore() const { +double Anime::GetAudienceScore() const +{ return info_.audience_score; } -std::string Anime::GetSynopsis() const { +std::string Anime::GetSynopsis() const +{ return info_.synopsis; } -int Anime::GetDuration() const { +int Anime::GetDuration() const +{ return info_.duration; } -std::string Anime::GetPosterUrl() const { +std::string Anime::GetPosterUrl() const +{ /* this isn't really service-specific. this could use * kitsu, MAL, or anilist, and would achieve basically * the same effect. */ return info_.poster_url; } -std::optional<std::string> Anime::GetServiceUrl(Service service) const { +std::optional<std::string> Anime::GetServiceUrl(Service service) const +{ /* todo: add support for other services... */ std::optional<std::string> id = GetServiceId(service); if (!id.has_value()) return std::nullopt; switch (service) { - case Service::AniList: - return "https://anilist.co/anime/" + id.value(); + case Service::AniList: return "https://anilist.co/anime/" + id.value(); default: return ""; } } -void Anime::SetId(int id) { +void Anime::SetId(int id) +{ info_.id = id; } -void Anime::SetServiceId(Service service, const std::string& id) { +void Anime::SetServiceId(Service service, const std::string &id) +{ info_.ids[service] = id; } -void Anime::SetTitle(TitleLanguage language, const std::string& title) { +void Anime::SetTitle(TitleLanguage language, const std::string &title) +{ info_.titles[language] = title; } -void Anime::SetTitleSynonyms(const std::vector<std::string>& synonyms) { +void Anime::SetTitleSynonyms(const std::vector<std::string> &synonyms) +{ info_.synonyms = synonyms; } -void Anime::AddTitleSynonym(const std::string& synonym) { +void Anime::AddTitleSynonym(const std::string &synonym) +{ info_.synonyms.push_back(synonym); } -void Anime::SetEpisodes(int episodes) { +void Anime::SetEpisodes(int episodes) +{ info_.episodes = episodes; } -void Anime::SetAiringStatus(SeriesStatus status) { +void Anime::SetAiringStatus(SeriesStatus status) +{ info_.status = status; } -void Anime::SetStartedDate(const Date& date) { +void Anime::SetStartedDate(const Date &date) +{ info_.started = date; } -void Anime::SetCompletedDate(const Date& date) { +void Anime::SetCompletedDate(const Date &date) +{ info_.completed = date; } -void Anime::SetGenres(const std::vector<std::string>& genres) { +void Anime::SetGenres(const std::vector<std::string> &genres) +{ info_.genres = genres; } -void Anime::SetProducers(const std::vector<std::string>& producers) { +void Anime::SetProducers(const std::vector<std::string> &producers) +{ info_.producers = producers; } -void Anime::SetFormat(SeriesFormat format) { +void Anime::SetFormat(SeriesFormat format) +{ info_.format = format; } -void Anime::SetAudienceScore(double audience_score) { +void Anime::SetAudienceScore(double audience_score) +{ info_.audience_score = audience_score; } -void Anime::SetSynopsis(std::string synopsis) { +void Anime::SetSynopsis(std::string synopsis) +{ info_.synopsis = synopsis; } -void Anime::SetDuration(int duration) { +void Anime::SetDuration(int duration) +{ info_.duration = duration; } -void Anime::SetPosterUrl(std::string url) { +void Anime::SetPosterUrl(std::string url) +{ info_.poster_url = url; } -std::string Anime::GetUserPreferredTitle() const { +std::string Anime::GetUserPreferredTitle() const +{ std::optional<std::string> title = GetTitle(session.config.anime_list.language); if (title.has_value()) return title.value();
--- a/src/core/anime_db.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/anime_db.cc Fri Jul 25 10:16:02 2025 -0400 @@ -12,40 +12,43 @@ #include <fstream> +#include <cstdlib> #include <exception> -#include <cstdlib> #include <iostream> #include <random> namespace Anime { -size_t Database::GetTotalAnimeAmount() const { +size_t Database::GetTotalAnimeAmount() const +{ size_t total = 0; - for (const auto& [id, anime] : items) + for (const auto &[id, anime] : items) if (anime.IsInUserList()) total++; return total; } -size_t Database::GetListsAnimeAmount(ListStatus status) const { +size_t Database::GetListsAnimeAmount(ListStatus status) const +{ if (status == ListStatus::NotInList) return 0; size_t total = 0; - for (const auto& [id, anime] : items) + for (const auto &[id, anime] : items) if (anime.IsInUserList() && anime.GetUserStatus() == status) total++; return total; } -size_t Database::GetTotalEpisodeAmount() const { +size_t Database::GetTotalEpisodeAmount() const +{ size_t total = 0; - for (const auto& [id, anime] : items) + for (const auto &[id, anime] : items) if (anime.IsInUserList()) total += anime.GetUserRewatchedTimes() * anime.GetEpisodes() + anime.GetUserProgress(); @@ -53,10 +56,11 @@ } /* Returns the total watched amount in minutes. */ -size_t Database::GetTotalWatchedAmount() const { +size_t Database::GetTotalWatchedAmount() const +{ size_t total = 0; - for (const auto& [id, anime] : items) + for (const auto &[id, anime] : items) if (anime.IsInUserList()) total += anime.GetDuration() * anime.GetUserProgress() + anime.GetEpisodes() * anime.GetDuration() * anime.GetUserRewatchedTimes(); @@ -69,10 +73,11 @@ amount of episodes, as AniList will let you set episode counts up to 32768. But that should rather be handled elsewhere. */ -size_t Database::GetTotalPlannedAmount() const { +size_t Database::GetTotalPlannedAmount() const +{ size_t total = 0; - for (const auto& [id, anime] : items) + for (const auto &[id, anime] : items) if (anime.IsInUserList()) total += anime.GetDuration() * (anime.GetEpisodes() - anime.GetUserProgress()); @@ -82,11 +87,12 @@ /* In Taiga this is called the mean, but "average" is what's primarily used in conversation, at least in the U.S. */ -double Database::GetAverageScore() const { +double Database::GetAverageScore() const +{ double avg = 0; size_t amt = 0; - for (const auto& [id, anime] : items) { + for (const auto &[id, anime] : items) { if (anime.IsInUserList() && anime.GetUserScore()) { avg += anime.GetUserScore(); amt++; @@ -95,11 +101,12 @@ return avg / amt; } -double Database::GetScoreDeviation() const { +double Database::GetScoreDeviation() const +{ double squares_sum = 0, avg = GetAverageScore(); size_t amt = 0; - for (const auto& [id, anime] : items) { + for (const auto &[id, anime] : items) { if (anime.IsInUserList() && anime.GetUserScore()) { squares_sum += std::pow(static_cast<double>(anime.GetUserScore()) - avg, 2); amt++; @@ -109,18 +116,19 @@ return (amt > 0) ? std::sqrt(squares_sum / amt) : 0; } -int Database::LookupAnimeTitle(const std::string& title) const { +int Database::LookupAnimeTitle(const std::string &title) const +{ if (title.empty()) return 0; std::string title_n(title); Strings::NormalizeAnimeTitle(title_n); - for (const auto& [id, anime] : items) { + for (const auto &[id, anime] : items) { std::vector<std::string> synonyms(anime.GetTitleSynonyms()); synonyms.push_back(anime.GetUserPreferredTitle()); - for (auto& synonym : synonyms) { + for (auto &synonym : synonyms) { Strings::NormalizeAnimeTitle(synonym); if (synonym == title_n) return id; @@ -130,7 +138,8 @@ return 0; } -static bool GetListDataAsJSON(const Anime& anime, nlohmann::json& json) { +static bool GetListDataAsJSON(const Anime &anime, nlohmann::json &json) +{ if (!anime.IsInUserList()) return false; @@ -152,7 +161,8 @@ return true; } -static bool GetAnimeAsJSON(const Anime& anime, nlohmann::json& json) { +static bool GetAnimeAsJSON(const Anime &anime, nlohmann::json &json) +{ // clang-format off json = { {"id", anime.GetId()}, @@ -173,13 +183,13 @@ // clang-format on /* now for dynamically-filled stuff */ - for (const auto& lang : TitleLanguages) { + for (const auto &lang : TitleLanguages) { std::optional<std::string> title = anime.GetTitle(lang); if (title.has_value()) json["title"][Strings::ToLower(Translate::ToString(lang))] = title.value(); } - for (const auto& service : Services) { + for (const auto &service : Services) { std::optional<std::string> id = anime.GetServiceId(service); if (id.has_value()) json["ids"][Strings::ToLower(Translate::ToString(service))] = id.value(); @@ -192,8 +202,9 @@ return true; } -bool Database::GetDatabaseAsJSON(nlohmann::json& json) const { - for (const auto& [id, anime] : items) { +bool Database::GetDatabaseAsJSON(nlohmann::json &json) const +{ + for (const auto &[id, anime] : items) { nlohmann::json anime_json = {}; GetAnimeAsJSON(anime, anime_json); json.push_back(anime_json); @@ -202,7 +213,8 @@ return true; } -bool Database::SaveDatabaseToDisk() const { +bool Database::SaveDatabaseToDisk() const +{ std::filesystem::path db_path = Filesystem::GetAnimeDBPath(); Filesystem::CreateDirectories(db_path); @@ -218,7 +230,8 @@ return true; } -static bool ParseAnimeUserInfoJSON(const nlohmann::json& json, Anime& anime) { +static bool ParseAnimeUserInfoJSON(const nlohmann::json &json, Anime &anime) +{ if (!anime.IsInUserList()) anime.AddToUserList(); @@ -236,22 +249,23 @@ return true; } -static bool ParseAnimeInfoJSON(const nlohmann::json& json, Database& database) { +static bool ParseAnimeInfoJSON(const nlohmann::json &json, Database &database) +{ int id = JSON::GetNumber(json, "/id"_json_pointer, 0); if (!id) return false; - Anime& anime = database.items[id]; + Anime &anime = database.items[id]; anime.SetId(id); - for (const auto& service : Services) { + for (const auto &service : Services) { nlohmann::json::json_pointer p("/ids/" + Strings::ToLower(Translate::ToString(service))); if (json.contains(p) && json[p].is_string()) anime.SetServiceId(service, json[p].get<std::string>()); } - for (const auto& lang : TitleLanguages) { + for (const auto &lang : TitleLanguages) { nlohmann::json::json_pointer p("/title/" + Strings::ToLower(Translate::ToString(lang))); if (json.contains(p) && json[p].is_string()) @@ -278,14 +292,16 @@ return true; } -bool Database::ParseDatabaseJSON(const nlohmann::json& json) { - for (const auto& anime_json : json) +bool Database::ParseDatabaseJSON(const nlohmann::json &json) +{ + for (const auto &anime_json : json) ParseAnimeInfoJSON(anime_json, *this); return true; } -bool Database::LoadDatabaseFromDisk() { +bool Database::LoadDatabaseFromDisk() +{ std::filesystem::path db_path = Filesystem::GetAnimeDBPath(); Filesystem::CreateDirectories(db_path); @@ -297,7 +313,7 @@ nlohmann::json json; try { json = json.parse(db_file); - } catch (std::exception const& ex) { + } catch (std::exception const &ex) { std::cerr << "[anime/db] Failed to parse JSON! " << ex.what() << std::endl; return false; } @@ -308,7 +324,8 @@ return true; } -int Database::GetUnusedId() const { +int Database::GetUnusedId() const +{ std::uniform_int_distribution<int> distrib(1, INT_MAX); int res; @@ -319,8 +336,9 @@ return res; } -int Database::LookupServiceId(Service service, const std::string& id_to_find) const { - for (const auto& [id, anime] : items) { +int Database::LookupServiceId(Service service, const std::string &id_to_find) const +{ + for (const auto &[id, anime] : items) { std::optional<std::string> service_id = anime.GetServiceId(service); if (!service_id) continue; @@ -332,7 +350,8 @@ return 0; } -int Database::LookupServiceIdOrUnused(Service service, const std::string& id_to_find) const { +int Database::LookupServiceIdOrUnused(Service service, const std::string &id_to_find) const +{ int id = LookupServiceId(service, id_to_find); if (id) return id; @@ -340,17 +359,19 @@ return GetUnusedId(); } -void Database::RemoveAllUserData() { - for (auto& [id, anime] : items) { +void Database::RemoveAllUserData() +{ + for (auto &[id, anime] : items) { if (anime.IsInUserList()) anime.RemoveFromUserList(); } } -std::vector<int> Database::GetAllAnimeForSeason(Season season) { +std::vector<int> Database::GetAllAnimeForSeason(Season season) +{ std::vector<int> res; - for (const auto& [id, anime] : items) { + for (const auto &[id, anime] : items) { if (anime.GetSeason() == season) res.push_back(id); }
--- a/src/core/anime_season.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/anime_season.cc Fri Jul 25 10:16:02 2025 -0400 @@ -3,49 +3,59 @@ namespace Anime { -static bool WinterStartsInDecember() { +static bool WinterStartsInDecember() +{ switch (session.config.service) { - case Service::MyAnimeList: - return false; - default: - return true; + case Service::MyAnimeList: return false; + default: return true; } } -static Season::Name GetSeasonForMonth(Date::Month month) { +static Season::Name GetSeasonForMonth(Date::Month month) +{ if (WinterStartsInDecember()) { switch (month) { - case Date::Month::Dec: case Date::Month::Jan: case Date::Month::Feb: - return Season::Name::Winter; - case Date::Month::Mar: case Date::Month::Apr: case Date::Month::May: - return Season::Name::Spring; - case Date::Month::Jun: case Date::Month::Jul: case Date::Month::Aug: - return Season::Name::Summer; - case Date::Month::Sep: case Date::Month::Oct: case Date::Month::Nov: - return Season::Name::Autumn; + case Date::Month::Dec: + case Date::Month::Jan: + case Date::Month::Feb: return Season::Name::Winter; + case Date::Month::Mar: + case Date::Month::Apr: + case Date::Month::May: return Season::Name::Spring; + case Date::Month::Jun: + case Date::Month::Jul: + case Date::Month::Aug: return Season::Name::Summer; + case Date::Month::Sep: + case Date::Month::Oct: + case Date::Month::Nov: return Season::Name::Autumn; default: return Season::Name::Unknown; } } else { switch (month) { - case Date::Month::Jan: case Date::Month::Feb: case Date::Month::Mar: - return Season::Name::Winter; - case Date::Month::Apr: case Date::Month::May: case Date::Month::Jun: - return Season::Name::Spring; - case Date::Month::Jul: case Date::Month::Aug: case Date::Month::Sep: - return Season::Name::Summer; - case Date::Month::Oct: case Date::Month::Nov: case Date::Month::Dec: - return Season::Name::Autumn; + case Date::Month::Jan: + case Date::Month::Feb: + case Date::Month::Mar: return Season::Name::Winter; + case Date::Month::Apr: + case Date::Month::May: + case Date::Month::Jun: return Season::Name::Spring; + case Date::Month::Jul: + case Date::Month::Aug: + case Date::Month::Sep: return Season::Name::Summer; + case Date::Month::Oct: + case Date::Month::Nov: + case Date::Month::Dec: return Season::Name::Autumn; default: return Season::Name::Unknown; } } } -Season::Season(Season::Name s, Date::Year y) { +Season::Season(Season::Name s, Date::Year y) +{ season = s; year = y; } -Season::Season(const Date& date) { +Season::Season(const Date &date) +{ std::optional<Date::Month> month = date.GetMonth(); if (month) season = GetSeasonForMonth(month.value()); @@ -55,45 +65,59 @@ year = y.value(); } -bool Season::operator==(const Season& o) const { +bool Season::operator==(const Season &o) const +{ return (season == o.season && year == o.year); } -bool Season::operator!=(const Season& o) const { +bool Season::operator!=(const Season &o) const +{ return !(*this == o); } -bool Season::operator<(const Season& o) const { +bool Season::operator<(const Season &o) const +{ return std::tie(season, year) < std::tie(o.season, o.year); } -bool Season::operator>(const Season& o) const { +bool Season::operator>(const Season &o) const +{ return (o < *this); } -bool Season::operator<=(const Season& o) const { +bool Season::operator<=(const Season &o) const +{ return !(o > *this); } -bool Season::operator>=(const Season& o) const { +bool Season::operator>=(const Season &o) const +{ return !(*this < o); } -Season& Season::operator++() { +Season &Season::operator++() +{ switch (season) { case Season::Name::Winter: season = Season::Name::Spring; break; case Season::Name::Spring: season = Season::Name::Summer; break; case Season::Name::Summer: season = Season::Name::Autumn; break; - case Season::Name::Autumn: season = Season::Name::Winter; year++; break; + case Season::Name::Autumn: + season = Season::Name::Winter; + year++; + break; default: season = Season::Name::Unknown; break; } return *this; } -Season& Season::operator--() { +Season &Season::operator--() +{ switch (season) { - case Season::Name::Winter: season = Season::Name::Autumn; year--; break; + case Season::Name::Winter: + season = Season::Name::Autumn; + year--; + break; case Season::Name::Spring: season = Season::Name::Winter; break; case Season::Name::Summer: season = Season::Name::Spring; break; case Season::Name::Autumn: season = Season::Name::Summer; break; @@ -103,4 +127,4 @@ return *this; } -} +} // namespace Anime
--- a/src/core/byte_stream.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/byte_stream.cc Fri Jul 25 10:16:02 2025 -0400 @@ -1,19 +1,23 @@ #include "core/byte_stream.h" -ByteStream::ByteStream(std::uint8_t *bytes, std::size_t size) { +ByteStream::ByteStream(std::uint8_t *bytes, std::size_t size) +{ bytes_ = bytes; size_ = size; } -void ByteStream::ResetOffset() { +void ByteStream::ResetOffset() +{ offset_ = 0; } -void ByteStream::SetEndianness(ByteStream::ByteOrder endian) { +void ByteStream::SetEndianness(ByteStream::ByteOrder endian) +{ endian_ = endian; } -bool ByteStream::ReadString(std::string& str, std::size_t size) { +bool ByteStream::ReadString(std::string &str, std::size_t size) +{ if (offset_ + size >= size_) return false; @@ -22,7 +26,8 @@ return true; } -bool ByteStream::Advance(std::size_t amount) { +bool ByteStream::Advance(std::size_t amount) +{ if (offset_ + amount >= size_) return false;
--- a/src/core/config.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/config.cc Fri Jul 25 10:16:02 2025 -0400 @@ -25,7 +25,8 @@ /* NOTE: This config file is prone to breakage, as Minori is alpha software and * as such nothing is constant. */ -int Config::Load() { +int Config::Load() +{ std::filesystem::path cfg_path = Filesystem::GetConfigPath(); std::ifstream ifs(cfg_path, std::ios_base::binary); @@ -36,7 +37,7 @@ try { data = toml::parse(ifs); - } catch (const std::exception& ex) { + } catch (const std::exception &ex) { std::cerr << "config: failed to parse toml with error " << ex.what() << std::endl; return 0; } @@ -45,26 +46,28 @@ locale.RefreshAvailableLocales(); locale.SetActiveLocale(QLocale(Strings::ToQString(toml::find_or(data, "General", "Locale", "en_US")))); - anime_list.score_format = Translate::ToScoreFormat(toml::find_or(data, "Anime List", "Score format", "100-point")); anime_list.language = Translate::ToLanguage(toml::find_or(data, "Anime List", "Title language", "Romaji")); anime_list.display_aired_episodes = toml::find_or(data, "Anime List", "Display only aired episodes", true); - anime_list.display_available_episodes = toml::find_or(data, "Anime List", "Display only available episodes in library", true); + anime_list.display_available_episodes = + toml::find_or(data, "Anime List", "Display only available episodes in library", true); anime_list.highlight_anime_if_available = toml::find_or(data, "Anime List", "Highlight anime if available", true); anime_list.highlighted_anime_above_others = - (anime_list.highlight_anime_if_available) - ? toml::find_or(data, "Anime List", "Display highlighted anime above others", false) - : false; + (anime_list.highlight_anime_if_available) + ? toml::find_or(data, "Anime List", "Display highlighted anime above others", false) + : false; auth.anilist.auth_token = toml::find_or(data, "Authentication/AniList", "Auth Token", ""); auth.anilist.user_id = toml::find_or(data, "Authentication/AniList", "User ID", 0); auth.kitsu.access_token = toml::find_or(data, "Authentication/Kitsu", "Access Token", ""); - auth.kitsu.access_token_expiration = toml::find_or(data, "Authentication/Kitsu", "Access Token Expiration", static_cast<Time::Timestamp>(0)); + auth.kitsu.access_token_expiration = + toml::find_or(data, "Authentication/Kitsu", "Access Token Expiration", static_cast<Time::Timestamp>(0)); auth.kitsu.refresh_token = toml::find_or(data, "Authentication/Kitsu", "Refresh Token", ""); auth.kitsu.user_id = toml::find_or(data, "Authentication/Kitsu", "User ID", ""); - torrents.feed_link = toml::find_or(data, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0"); + torrents.feed_link = + toml::find_or(data, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0"); recognition.detect_media_players = toml::find_or(data, "Recognition", "Detect media players", true); @@ -82,11 +85,11 @@ return false; recognition.players.reserve(players.size()); - for (const auto& player : players) + for (const auto &player : players) recognition.players.push_back({true, player}); } - for (auto& [enabled, player] : recognition.players) { + for (auto &[enabled, player] : recognition.players) { switch (player.type) { default: case animone::PlayerType::Default: @@ -98,13 +101,12 @@ } } - theme.SetTheme(Translate::ToTheme(toml::find_or(data, "Appearance", "Theme", "Default"))); if (data.contains("Library") && data["Library"].contains("Folders")) { - const toml::value& folders = toml::find(data, "Library", "Folders"); + const toml::value &folders = toml::find(data, "Library", "Folders"); std::vector<std::string> v = toml::get_or<std::vector<std::string>>(folders, {}); - for (const auto& s : v) + for (const auto &s : v) if (!library.paths.count(s)) library.paths.insert(s); } @@ -114,7 +116,8 @@ return 0; } -int Config::Save() { +int Config::Save() +{ std::filesystem::path cfg_path = Filesystem::GetConfigPath(); Filesystem::CreateDirectories(cfg_path); @@ -127,8 +130,9 @@ data["Library"]["Folders"] = library.paths; data["Library"]["Real-time monitor"] = library.real_time_monitor; - for (const auto& [enabled, player] : recognition.players) { - const std::string section = (player.type == animone::PlayerType::WebBrowser) ? "Recognition/Players" : "Recognition/Browsers"; + for (const auto &[enabled, player] : recognition.players) { + const std::string section = + (player.type == animone::PlayerType::WebBrowser) ? "Recognition/Players" : "Recognition/Browsers"; data[section][player.name] = enabled; }
--- a/src/core/date.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/date.cc Fri Jul 25 10:16:02 2025 -0400 @@ -1,6 +1,6 @@ #include "core/date.h" +#include "core/json.h" #include "core/time.h" -#include "core/json.h" #include <QDate> #include <QDebug> @@ -10,20 +10,24 @@ /* An implementation of AniList's "fuzzy date" */ -Date::Date() { +Date::Date() +{ } -Date::Date(Date::Year y) { +Date::Date(Date::Year y) +{ SetYear(y); } -Date::Date(Date::Year y, Date::Month m, Date::Day d) { +Date::Date(Date::Year y, Date::Month m, Date::Day d) +{ SetYear(y); SetMonth(m); SetDay(d); } -Date::Date(const std::string& str) { +Date::Date(const std::string &str) +{ unsigned int y, m, d; /* I don't like this that much, but it works... */ @@ -39,7 +43,8 @@ SetDay(d); } -Date::Date(const QDate& date) { +Date::Date(const QDate &date) +{ SetYear(date.year()); auto m = date.month(); m = std::clamp(m, static_cast<decltype(m)>(Date::Month::Jan), static_cast<decltype(m)>(Date::Month::Dec)); @@ -47,7 +52,8 @@ SetDay(date.day()); } -Date::Date(const nlohmann::json& json) { +Date::Date(const nlohmann::json &json) +{ /* NOTE: this constructor is made for use with * AniList FuzzyDate-style JSON. In the future, some other * methods may be parsed and whatnot if necessary. */ @@ -65,51 +71,63 @@ SetDay(json.at("/day"_json_pointer).get<unsigned char>()); } -Date::Date(Time::Timestamp timestamp) { +Date::Date(Time::Timestamp timestamp) +{ Date(QDateTime::fromSecsSinceEpoch(timestamp).date()); } -void Date::VoidYear() { +void Date::VoidYear() +{ year.reset(); } -void Date::VoidMonth() { +void Date::VoidMonth() +{ month.reset(); } -void Date::VoidDay() { +void Date::VoidDay() +{ day.reset(); } -void Date::SetYear(Date::Year y) { +void Date::SetYear(Date::Year y) +{ year.emplace(y); } -void Date::SetMonth(Date::Month m) { +void Date::SetMonth(Date::Month m) +{ month.emplace(m); } -void Date::SetDay(Date::Day d) { +void Date::SetDay(Date::Day d) +{ day.emplace(std::clamp(d, static_cast<Date::Day>(1U), static_cast<Date::Day>(31U))); } -std::optional<Date::Year> Date::GetYear() const { +std::optional<Date::Year> Date::GetYear() const +{ return year; } -std::optional<Date::Month> Date::GetMonth() const { +std::optional<Date::Month> Date::GetMonth() const +{ return month; } -std::optional<Date::Day> Date::GetDay() const { +std::optional<Date::Day> Date::GetDay() const +{ return day; } -bool Date::IsValid() const { +bool Date::IsValid() const +{ return year.has_value() && month.has_value() && day.has_value(); } -QDate Date::GetAsQDate() const { +QDate Date::GetAsQDate() const +{ /* QDate doesn't support "missing" values (for good reason), * so we do our best and return what we can. */ @@ -117,7 +135,8 @@ return QDate(year.value_or(2000), static_cast<unsigned int>(month.value_or(Date::Month::Jan)), day.value_or(1)); } -nlohmann::json Date::GetAsAniListJson() const { +nlohmann::json Date::GetAsAniListJson() const +{ nlohmann::json json = { {"year", nullptr}, {"month", nullptr},
--- a/src/core/filesystem.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/filesystem.cc Fri Jul 25 10:16:02 2025 -0400 @@ -10,16 +10,18 @@ /* this runs fs::create_directories() on the PARENT directory. */ -void CreateDirectories(const std::filesystem::path& path) { +void CreateDirectories(const std::filesystem::path &path) +{ if (path.empty()) return; - const auto& parent = path.parent_path(); + const auto &parent = path.parent_path(); if (!std::filesystem::exists(parent)) std::filesystem::create_directories(parent); } -std::filesystem::path GetDotPath() { +std::filesystem::path GetDotPath() +{ /* * Windows: ~/AppData/Roaming/Minori * macOS: ~/Library/Application Support/Minori @@ -34,15 +36,18 @@ #endif } -std::filesystem::path GetConfigPath() { +std::filesystem::path GetConfigPath() +{ return GetDotPath() / CONFIG_NAME; } -std::filesystem::path GetAnimeDBPath() { +std::filesystem::path GetAnimeDBPath() +{ return GetDotPath() / "anime" / "db.json"; } -std::filesystem::path GetTorrentsPath() { +std::filesystem::path GetTorrentsPath() +{ return GetDotPath() / "torrents"; }
--- a/src/core/http.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/http.cc Fri Jul 25 10:16:02 2025 -0400 @@ -8,13 +8,14 @@ namespace HTTP { -std::string UrlEncode(const std::string& data) { +std::string UrlEncode(const std::string &data) +{ /* why do I need to init curl just for this? wtf? */ CURL *curl = curl_easy_init(); if (!curl) return ""; /* no way! */ - char* output = curl_easy_escape(curl, data.data(), data.size()); + char *output = curl_easy_escape(curl, data.data(), data.size()); if (!output) { curl_easy_cleanup(curl); return ""; @@ -28,13 +29,14 @@ return str; } -std::string UrlDecode(const std::string& data) { +std::string UrlDecode(const std::string &data) +{ CURL *curl = curl_easy_init(); if (!curl) return ""; int outlength; - char* output = curl_easy_unescape(curl, data.data(), data.size(), &outlength); + char *output = curl_easy_unescape(curl, data.data(), data.size(), &outlength); if (!output) { curl_easy_cleanup(curl); return ""; @@ -48,9 +50,10 @@ return str; } -std::string EncodeParamsList(std::string base, const std::map<std::string, std::string>& params) { +std::string EncodeParamsList(std::string base, const std::map<std::string, std::string> ¶ms) +{ std::size_t count = 0; - for (const auto& param : params) { + for (const auto ¶m : params) { base += (!count ? "?" : "&"); base += UrlEncode(param.first); base += "="; @@ -62,18 +65,20 @@ return base; } -static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { - reinterpret_cast<QByteArray*>(userdata)->append(reinterpret_cast<char*>(contents), size * nmemb); +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata) +{ + reinterpret_cast<QByteArray *>(userdata)->append(reinterpret_cast<char *>(contents), size * nmemb); return size * nmemb; } -QByteArray Request(const std::string& url, const std::vector<std::string>& headers, const std::string& data, Type type) { - struct curl_slist* list = NULL; +QByteArray Request(const std::string &url, const std::vector<std::string> &headers, const std::string &data, Type type) +{ + struct curl_slist *list = NULL; QByteArray userdata; - CURL* curl = curl_easy_init(); + CURL *curl = curl_easy_init(); if (curl) { - for (const std::string& h : headers) + for (const std::string &h : headers) list = curl_slist_append(list, h.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); @@ -95,8 +100,9 @@ } /* this function is static */ -size_t RequestThread::WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { - RequestThread* thread = reinterpret_cast<RequestThread*>(userdata); +size_t RequestThread::WriteCallback(void *contents, size_t size, size_t nmemb, void *userdata) +{ + RequestThread *thread = reinterpret_cast<RequestThread *>(userdata); const std::lock_guard<std::mutex> lock(thread->callback_data_mutex_); @@ -105,56 +111,64 @@ return CURL_WRITEFUNC_ERROR; /* else, continue on as normal */ - thread->array_.append(reinterpret_cast<char*>(contents), size * nmemb); + thread->array_.append(reinterpret_cast<char *>(contents), size * nmemb); return size * nmemb; } -RequestThread::RequestThread(Type type, QObject* parent) : QThread(parent) { +RequestThread::RequestThread(Type type, QObject *parent) : QThread(parent) +{ SetType(type); } -RequestThread::RequestThread(const std::string& url, const std::vector<std::string>& headers, - const std::string& data, Type type, QObject* parent) - : QThread(parent) { +RequestThread::RequestThread(const std::string &url, const std::vector<std::string> &headers, const std::string &data, + Type type, QObject *parent) + : QThread(parent) +{ SetUrl(url); SetData(data); SetHeaders(headers); SetType(type); } -RequestThread::~RequestThread() { +RequestThread::~RequestThread() +{ /* block until the function can safely exit */ Stop(); wait(); } -void RequestThread::SetUrl(const std::string& url) { +void RequestThread::SetUrl(const std::string &url) +{ url_ = url; } -void RequestThread::SetHeaders(const std::vector<std::string>& headers) { +void RequestThread::SetHeaders(const std::vector<std::string> &headers) +{ headers_ = headers; } -void RequestThread::SetData(const std::string& data) { +void RequestThread::SetData(const std::string &data) +{ data_ = data; } -void RequestThread::SetType(Type type) { +void RequestThread::SetType(Type type) +{ type_ = type; } -void RequestThread::run() { - struct curl_slist* list = NULL; +void RequestThread::run() +{ + struct curl_slist *list = NULL; - CURL* curl = curl_easy_init(); + CURL *curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); if (type_ == Type::Post) curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data_.c_str()); - for (const std::string& h : headers_) + for (const std::string &h : headers_) list = curl_slist_append(list, h.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); @@ -181,7 +195,8 @@ array_.clear(); } -void RequestThread::Stop() { +void RequestThread::Stop() +{ const std::lock_guard<std::mutex> lock(callback_data_mutex_); cancelled_ = true; }
--- a/src/core/json.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/json.cc Fri Jul 25 10:16:02 2025 -0400 @@ -3,14 +3,16 @@ namespace JSON { -nlohmann::json GetValue(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr) { +nlohmann::json GetValue(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr) +{ if (json.contains(ptr)) return json.at(ptr); else return nlohmann::json(); } -bool GetBoolean(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, bool def) { +bool GetBoolean(const nlohmann::json &json, const nlohmann::json::json_pointer &ptr, bool def) +{ if (json.contains(ptr) && json[ptr].is_boolean()) return json[ptr].get<bool>(); else
--- a/src/core/session.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/session.cc Fri Jul 25 10:16:02 2025 -0400 @@ -1,8 +1,8 @@ #include "core/session.h" -#include "core/strings.h" #include "core/config.h" +#include "core/strings.h" +#include "gui/locale.h" #include "gui/window.h" -#include "gui/locale.h" #include <QElapsedTimer> #include <QStatusBar> @@ -13,28 +13,34 @@ Session session; -Session::Session() : gen(Time::GetSystemTime()) { +Session::Session() : gen(Time::GetSystemTime()) +{ timer_.start(); } -void Session::SetMainWindow(MainWindow* window) { +void Session::SetMainWindow(MainWindow *window) +{ disconnect(); window_ = window; connect(this, &Session::StatusBarChange, window_, &MainWindow::SetStatusMessage); } -void Session::SetStatusBar(const std::string& message) { +void Session::SetStatusBar(const std::string &message) +{ emit StatusBarChange(message); } -void Session::IncrementRequests() { +void Session::IncrementRequests() +{ requests_++; }; -unsigned int Session::GetRequests() { +unsigned int Session::GetRequests() +{ return requests_; }; -int Session::uptime() { +int Session::uptime() +{ return timer_.elapsed(); }
--- a/src/core/strings.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/strings.cc Fri Jul 25 10:16:02 2025 -0400 @@ -5,17 +5,17 @@ #include "core/session.h" // locale #include <QByteArray> +#include <QCoreApplication> #include <QDebug> #include <QLocale> #include <QString> #include <QTextDocument> -#include <QCoreApplication> #include <algorithm> #include <cctype> #include <codecvt> +#include <iomanip> #include <iostream> -#include <iomanip> #include <locale> #include <string> #include <unordered_map> @@ -26,7 +26,8 @@ namespace Strings { /* ew */ -std::string Implode(const std::vector<std::string>& vector, const std::string& delimiter) { +std::string Implode(const std::vector<std::string> &vector, const std::string &delimiter) +{ if (vector.size() < 1) return ""; @@ -41,7 +42,8 @@ return out; } -std::vector<std::string> Split(const std::string& text, const std::string& delimiter) { +std::vector<std::string> Split(const std::string &text, const std::string &delimiter) +{ if (text.length() < 1) return {}; @@ -60,7 +62,8 @@ /* This function is really only used for cleaning up the synopsis of * horrible HTML debris from AniList :) */ -void ReplaceAll(std::string& string, std::string_view find, std::string_view replace) { +void ReplaceAll(std::string &string, std::string_view find, std::string_view replace) +{ size_t pos = 0; while ((pos = string.find(find, pos)) != std::string::npos) { string.replace(pos, find.length(), replace); @@ -68,51 +71,57 @@ } } -void ConvertRomanNumerals(std::string& string) { +void ConvertRomanNumerals(std::string &string) +{ static const std::vector<std::pair<std::string_view, std::string_view>> vec = { - {"2", "II"}, {"3", "III"}, {"4", "IV"}, {"5", "V"}, {"6", "VI"}, - {"7", "VII"}, {"8", "VIII"}, {"9", "IX"}, {"11", "XI"}, {"12", "XII"}, - {"13", "XIII"} - }; + {"2", "II" }, + {"3", "III" }, + {"4", "IV" }, + {"5", "V" }, + {"6", "VI" }, + {"7", "VII" }, + {"8", "VIII"}, + {"9", "IX" }, + {"11", "XI" }, + {"12", "XII" }, + {"13", "XIII"} + }; - for (const auto& item : vec) + for (const auto &item : vec) ReplaceAll(string, item.second, item.first); } /* this also performs case folding, so our string is lowercase after this */ -void NormalizeUnicode(std::string& string) { +void NormalizeUnicode(std::string &string) +{ static constexpr utf8proc_option_t options = static_cast<utf8proc_option_t>( - UTF8PROC_COMPAT | UTF8PROC_COMPOSE | UTF8PROC_STABLE | - UTF8PROC_IGNORE | UTF8PROC_STRIPCC | UTF8PROC_STRIPMARK | - UTF8PROC_LUMP | UTF8PROC_CASEFOLD | UTF8PROC_NLF2LS - ); + UTF8PROC_COMPAT | UTF8PROC_COMPOSE | UTF8PROC_STABLE | UTF8PROC_IGNORE | UTF8PROC_STRIPCC | UTF8PROC_STRIPMARK | + UTF8PROC_LUMP | UTF8PROC_CASEFOLD | UTF8PROC_NLF2LS); /* ack */ - utf8proc_uint8_t* buf = nullptr; + utf8proc_uint8_t *buf = nullptr; - const utf8proc_ssize_t size = utf8proc_map( - reinterpret_cast<const utf8proc_uint8_t*>(string.data()), - string.size(), - &buf, - options - ); + const utf8proc_ssize_t size = + utf8proc_map(reinterpret_cast<const utf8proc_uint8_t *>(string.data()), string.size(), &buf, options); if (buf) { if (size) - string.assign(reinterpret_cast<const char*>(buf), size); + string.assign(reinterpret_cast<const char *>(buf), size); std::free(buf); } } -void NormalizeAnimeTitle(std::string& string) { +void NormalizeAnimeTitle(std::string &string) +{ ConvertRomanNumerals(string); NormalizeUnicode(string); RemoveLeadingChars(string, ' '); RemoveTrailingChars(string, ' '); } -void TextifySynopsis(std::string& string) { +void TextifySynopsis(std::string &string) +{ /* Just let Qt deal with it. */ QTextDocument text; text.setHtml(Strings::ToQString(string)); @@ -122,102 +131,116 @@ /* let Qt handle the heavy lifting of locale shit * I don't want to deal with */ -std::string ToUpper(const std::string& string) { +std::string ToUpper(const std::string &string) +{ return ToUtf8String(session.config.locale.GetLocale().toUpper(ToQString(string))); } -std::string ToLower(const std::string& string) { +std::string ToLower(const std::string &string) +{ return ToUtf8String(session.config.locale.GetLocale().toLower(ToQString(string))); } -std::wstring ToWstring(const std::string& string) { +std::wstring ToWstring(const std::string &string) +{ static std::wstring_convert<std::codecvt_utf8<wchar_t>> converter("", L""); std::wstring wstr; try { wstr = converter.from_bytes(string); - } catch (std::range_error const& ex) { + } catch (std::range_error const &ex) { /* XXX how? */ std::cerr << "Failed to convert UTF-8 to wide string!" << std::endl; } return wstr; } -std::wstring ToWstring(const QString& string) { +std::wstring ToWstring(const QString &string) +{ std::wstring arr(string.size(), L'\0'); string.toWCharArray(&arr.front()); return arr; } -std::string ToUtf8String(const std::wstring& wstring) { +std::string ToUtf8String(const std::wstring &wstring) +{ static std::wstring_convert<std::codecvt_utf8<wchar_t>> converter("", L""); return converter.to_bytes(wstring); } -std::string ToUtf8String(const std::u32string& u32string) { +std::string ToUtf8String(const std::u32string &u32string) +{ static std::wstring_convert<std::codecvt_utf8_utf16<char32_t>, char32_t> converter; return converter.to_bytes(u32string); } -std::u32string ToUcs4String(const std::string& string) { +std::u32string ToUcs4String(const std::string &string) +{ static std::wstring_convert<std::codecvt_utf8_utf16<char32_t>, char32_t> converter; return converter.from_bytes(string); } -std::string ToUtf8String(const QString& string) { +std::string ToUtf8String(const QString &string) +{ const QByteArray ba = string.toUtf8(); return std::string(ba.constData(), ba.size()); } -std::string ToUtf8String(const QByteArray& ba) { +std::string ToUtf8String(const QByteArray &ba) +{ return std::string(ba.constData(), ba.size()); } -QString ToQString(const std::string& string) { +QString ToQString(const std::string &string) +{ return QString::fromUtf8(string.c_str(), string.length()); } -QString ToQString(const std::wstring& wstring) { +QString ToQString(const std::wstring &wstring) +{ return QString::fromWCharArray(wstring.c_str(), wstring.length()); } -std::string ToUtf8String(const bool b) { +std::string ToUtf8String(const bool b) +{ return b ? "true" : "false"; // lol } -bool ToBool(const std::string& str, bool def) { +bool ToBool(const std::string &str, bool def) +{ std::istringstream s(Strings::ToLower(str)); s >> std::boolalpha >> def; return def; } template<typename T> -constexpr T ipow(T num, unsigned int pow) { - return (pow >= sizeof(unsigned int)*8) ? 0 : - pow == 0 ? 1 : num * ipow(num, pow-1); +constexpr T ipow(T num, unsigned int pow) +{ + return (pow >= sizeof(unsigned int) * 8) ? 0 : pow == 0 ? 1 : num * ipow(num, pow - 1); } /* util funcs */ -uint64_t HumanReadableSizeToBytes(const std::string& str) { +uint64_t HumanReadableSizeToBytes(const std::string &str) +{ static const std::unordered_map<std::string, uint64_t> bytes_map = { - {"KB", 1e3}, - {"MB", 1e6}, - {"GB", 1e9}, - {"TB", 1e12}, - {"PB", 1e15}, - {"KiB", 1ull << 10}, - {"MiB", 1ull << 20}, - {"GiB", 1ull << 30}, + {"KB", 1e3 }, + {"MB", 1e6 }, + {"GB", 1e9 }, + {"TB", 1e12 }, + {"PB", 1e15 }, + {"KiB", 1ull << 10}, + {"MiB", 1ull << 20}, + {"GiB", 1ull << 30}, {"TiB", 1ull << 40}, - {"PiB", 1ull << 50} /* surely we won't need more than this */ + {"PiB", 1ull << 50} /* surely we won't need more than this */ }; - for (const auto& suffix : bytes_map) { + for (const auto &suffix : bytes_map) { if (str.find(suffix.first) != std::string::npos) { try { uint64_t size = std::stod(str) * suffix.second; return size; - } catch (std::invalid_argument const& ex) { + } catch (std::invalid_argument const &ex) { continue; } } @@ -226,27 +249,26 @@ return ToInt(str, 0); } -std::string BytesToHumanReadableSize(uint64_t bytes, int precision) { +std::string BytesToHumanReadableSize(uint64_t bytes, int precision) +{ #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) /* QLocale in Qt >= 5.10.0 has a function for this */ return Strings::ToUtf8String(session.config.locale.GetLocale().formattedDataSize(bytes, precision)); #else static const std::unordered_map<uint64_t, std::string> map = { - {1ull << 10, "KiB"}, - {1ull << 20, "MiB"}, - {1ull << 30, "GiB"}, - {1ull << 40, "TiB"}, - {1ull << 50, "PiB"} - }; + {1ull << 10, "KiB"}, + {1ull << 20, "MiB"}, + {1ull << 30, "GiB"}, + {1ull << 40, "TiB"}, + {1ull << 50, "PiB"} + }; - for (const auto& suffix : map) { + for (const auto &suffix : map) { if (bytes / suffix.first < 1) continue; std::stringstream ss; - ss << std::setprecision(precision) - << (static_cast<double>(bytes) / suffix.first) << " " - << suffix.second; + ss << std::setprecision(precision) << (static_cast<double>(bytes) / suffix.first) << " " << suffix.second; return ss.str(); } @@ -255,15 +277,18 @@ #endif } -void RemoveLeadingChars(std::string& s, const char c) { +void RemoveLeadingChars(std::string &s, const char c) +{ s.erase(0, std::min(s.find_first_not_of(c), s.size() - 1)); } -void RemoveTrailingChars(std::string& s, const char c) { +void RemoveTrailingChars(std::string &s, const char c) +{ s.erase(s.find_last_not_of(c) + 1, std::string::npos); } -bool BeginningMatchesSubstring(const std::string& str, const std::string& sub) { +bool BeginningMatchesSubstring(const std::string &str, const std::string &sub) +{ for (unsigned long long i = 0; i < str.length() && i < sub.length(); i++) if (str[i] != sub[i]) return false; @@ -271,7 +296,8 @@ return true; } -std::string Translate(const char* str) { +std::string Translate(const char *str) +{ return Strings::ToUtf8String(QCoreApplication::tr(str)); }
--- a/src/core/time.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/core/time.cc Fri Jul 25 10:16:02 2025 -0400 @@ -11,22 +11,26 @@ namespace Time { -static Timestamp GetSecondsInMinutes(Timestamp length) { +static Timestamp GetSecondsInMinutes(Timestamp length) +{ return std::llround(static_cast<double>(length) / 60.0); } -static Timestamp GetSecondsInHours(Timestamp length) { +static Timestamp GetSecondsInHours(Timestamp length) +{ return std::llround(static_cast<double>(length) / 3600.0); } -static Timestamp GetSecondsInDays(Timestamp length) { +static Timestamp GetSecondsInDays(Timestamp length) +{ return std::llround(static_cast<double>(length) / 86400.0); } -std::string GetSecondsAsRelativeString(Timestamp length) { +std::string GetSecondsAsRelativeString(Timestamp length) +{ std::string result; - auto get = [](Timestamp val, const std::string& s, const std::string& p) { + auto get = [](Timestamp val, const std::string &s, const std::string &p) { return Strings::ToUtf8String(val) + " " + (val == 1 ? s : p); }; @@ -53,7 +57,8 @@ /* "amount" does not have to be in seconds, and can be any unit if the correct ratio to seconds * is passed to "unit_in_seconds" (for example, if the input is minutes, pass 60.0) */ -std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds) { +std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds) +{ /* avoid calculating this twice */ const double years_conv = (31556952.0 / unit_in_seconds); const double months_conv = (2629746.0 / unit_in_seconds); @@ -69,8 +74,8 @@ const int minutes = std::fmod(amount, hours_conv) / minutes_conv; const int seconds = std::fmod(amount, minutes_conv) / seconds_conv; - const auto add_time_segment = [](std::ostringstream& str, int64_t amount, const std::string_view& singular, - const std::string_view& plural, bool always = false) { + const auto add_time_segment = [](std::ostringstream &str, int64_t amount, const std::string_view &singular, + const std::string_view &plural, bool always = false) { if (amount > 0 || always) str << amount << ((amount == 1) ? singular : plural); }; @@ -94,11 +99,13 @@ return string.str(); } -Timestamp GetSystemTime() { +Timestamp GetSystemTime() +{ return QDateTime::currentDateTime().toUTC().toSecsSinceEpoch(); } -Timestamp ParseISO8601Time(const std::string& str) { +Timestamp ParseISO8601Time(const std::string &str) +{ return QDateTime::fromString(Strings::ToQString(str), Qt::ISODateWithMs).toUTC().toSecsSinceEpoch(); }
--- a/src/gui/locale.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/gui/locale.cc Fri Jul 25 10:16:02 2025 -0400 @@ -11,7 +11,8 @@ namespace Locale { -std::string GetLocaleFullName(const QLocale& locale) { +std::string GetLocaleFullName(const QLocale &locale) +{ QString res = QLocale::languageToString(locale.language()); #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) /* silence deprecation warning for locale.country() */ @@ -24,25 +25,30 @@ return Strings::ToUtf8String(res); } -Locale::Locale() { +Locale::Locale() +{ RefreshAvailableLocales(); SetActiveLocale(QLocale("en_US")); } -Locale::Locale(const std::string& name) { +Locale::Locale(const std::string &name) +{ RefreshAvailableLocales(); SetActiveLocale(QLocale(Strings::ToQString(name))); } -QLocale Locale::GetLocale() const { +QLocale Locale::GetLocale() const +{ return _locale; } -std::vector<QLocale> Locale::GetAvailableLocales() const { +std::vector<QLocale> Locale::GetAvailableLocales() const +{ return _available_translations; } -void Locale::RefreshAvailableLocales() { +void Locale::RefreshAvailableLocales() +{ _available_translations.clear(); /* we will always have en_US */ @@ -55,18 +61,20 @@ QStringList translations = dir.entryList({"*.qm"}, QDir::Files); _available_translations.reserve(translations.size()); - for (const QString& str : translations) + for (const QString &str : translations) _available_translations.push_back(QLocale(str.mid(0, str.lastIndexOf(".")))); } -bool Locale::IsLocaleAvailable(const QLocale& locale) const { - for (const QLocale& l : _available_translations) +bool Locale::IsLocaleAvailable(const QLocale &locale) const +{ + for (const QLocale &l : _available_translations) if (l == locale) return true; return false; } -bool Locale::SetActiveLocale(const QLocale& locale) { +bool Locale::SetActiveLocale(const QLocale &locale) +{ if (!IsLocaleAvailable(locale) || !qApp) return false; @@ -99,7 +107,8 @@ return return_value; } -bool Locale::SwitchTranslator(QTranslator& translator, const QString& path) { +bool Locale::SwitchTranslator(QTranslator &translator, const QString &path) +{ qApp->removeTranslator(&translator); if (!translator.load(path))
--- a/src/gui/theme.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/gui/theme.cc Fri Jul 25 10:16:02 2025 -0400 @@ -1,24 +1,24 @@ +#include "gui/theme.h" #include "core/config.h" #include "core/session.h" -#include "gui/theme.h" #include <QApplication> #include <QDebug> #include <QFile> +#include <QStyle> #include <QStyleFactory> #include <QTextStream> -#include <QStyle> #include <QtGlobal> #ifdef MACOSX -# include "sys/osx/dark_theme.h" +# include "sys/osx/dark_theme.h" #elif defined(WIN32) -# include "sys/win32/dark_theme.h" +# include "sys/win32/dark_theme.h" #else -# ifdef GLIB -# include "sys/glib/dark_theme.h" -# endif -# ifdef HAVE_XCB -# include "sys/x11/dark_theme.h" -# endif +# ifdef GLIB +# include "sys/glib/dark_theme.h" +# endif +# ifdef HAVE_XCB +# include "sys/x11/dark_theme.h" +# endif #endif /* Weird quirks of this implementation: @@ -30,15 +30,18 @@ namespace Theme { -ThemeManager::ThemeManager(Theme theme) { +ThemeManager::ThemeManager(Theme theme) +{ this->theme = theme; } -Theme ThemeManager::GetTheme() const { +Theme ThemeManager::GetTheme() const +{ return theme; } -bool ThemeManager::IsInDarkTheme() const { +bool ThemeManager::IsInDarkTheme() const +{ switch (theme) { case Theme::Default: #ifdef MACOSX @@ -48,23 +51,23 @@ if (win32::DarkThemeAvailable()) return win32::IsInDarkTheme(); #else -# ifdef HAVE_XCB +# ifdef HAVE_XCB if (x11::IsInDarkTheme()) return true; -# endif -# ifdef GLIB +# endif +# ifdef GLIB if (glib::IsInDarkTheme()) return true; -# endif +# endif break; #endif - default: - break; + default: break; } return (theme == Theme::Dark); } -void ThemeManager::SetToDarkTheme() { +void ThemeManager::SetToDarkTheme() +{ /* macOS >= 10.14 has its own global dark theme, use it :) */ #ifdef MACOSX @@ -78,7 +81,8 @@ SetStyleSheet(Theme::Dark); } -void ThemeManager::SetToLightTheme() { +void ThemeManager::SetToLightTheme() +{ #ifdef MACOSX if (osx::DarkThemeAvailable()) osx::SetToLightTheme(); @@ -90,12 +94,14 @@ SetStyleSheet(Theme::Light); } -Theme ThemeManager::GetCurrentOSTheme() const { +Theme ThemeManager::GetCurrentOSTheme() const +{ return IsInDarkTheme() ? Theme::Dark : Theme::Light; } /* this function is private, and should stay that way */ -void ThemeManager::SetStyleSheet(Theme theme) { +void ThemeManager::SetStyleSheet(Theme theme) +{ switch (theme) { case Theme::Dark: { const QColor darkGray(53, 53, 53); @@ -151,7 +157,8 @@ } } -void ThemeManager::SetTheme(Theme theme) { +void ThemeManager::SetTheme(Theme theme) +{ switch (theme) { case Theme::Light: SetToLightTheme(); break; case Theme::Dark: SetToDarkTheme(); break; @@ -165,7 +172,8 @@ this->theme = theme; } -void ThemeManager::RepaintCurrentTheme() { +void ThemeManager::RepaintCurrentTheme() +{ SetTheme(theme); }
--- a/src/gui/window.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/gui/window.cc Fri Jul 25 10:16:02 2025 -0400 @@ -43,41 +43,47 @@ #include <iostream> #ifdef MACOSX -# include "sys/osx/dark_theme.h" -# include "sys/osx/permissions.h" +# include "sys/osx/dark_theme.h" +# include "sys/osx/permissions.h" #elif defined(WIN32) -# include "sys/win32/dark_theme.h" +# include "sys/win32/dark_theme.h" #endif -void MainWindowPlayingThread::run() { +void MainWindowPlayingThread::run() +{ std::vector<std::string> files; Track::Media::GetCurrentlyPlaying(files); emit Done(files); } -MainWindowAsyncSynchronizeThread::MainWindowAsyncSynchronizeThread(QAction* action, AnimeListPage* page, QObject* parent) : QThread(parent) { +MainWindowAsyncSynchronizeThread::MainWindowAsyncSynchronizeThread(QAction *action, AnimeListPage *page, + QObject *parent) + : QThread(parent) +{ SetAction(action); SetPage(page); } -void MainWindowAsyncSynchronizeThread::SetAction(QAction* action) { +void MainWindowAsyncSynchronizeThread::SetAction(QAction *action) +{ action_ = action; } -void MainWindowAsyncSynchronizeThread::SetPage(AnimeListPage* page) { +void MainWindowAsyncSynchronizeThread::SetPage(AnimeListPage *page) +{ page_ = page; } -void MainWindowAsyncSynchronizeThread::run() { +void MainWindowAsyncSynchronizeThread::run() +{ action_->setEnabled(false); Services::Synchronize(); page_->Refresh(); action_->setEnabled(true); } -MainWindow::MainWindow(QWidget* parent) - : QMainWindow(parent) - , async_synchronize_thread_(nullptr, nullptr) { +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), async_synchronize_thread_(nullptr, nullptr) +{ sidebar_.setFixedWidth(128); sidebar_.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); @@ -101,14 +107,14 @@ sidebar_.SetCurrentItem(static_cast<int>(Pages::ANIME_LIST)); setCentralWidget(&main_widget_); - NowPlayingPage* page = reinterpret_cast<NowPlayingPage*>(stack_.widget(static_cast<int>(Pages::NOW_PLAYING))); + NowPlayingPage *page = reinterpret_cast<NowPlayingPage *>(stack_.widget(static_cast<int>(Pages::NOW_PLAYING))); - connect(&playing_thread_, &MainWindowPlayingThread::Done, this, [page](const std::vector<std::string>& files) { - for (const auto& file : files) { + connect(&playing_thread_, &MainWindowPlayingThread::Done, this, [page](const std::vector<std::string> &files) { + for (const auto &file : files) { anitomy::Anitomy anitomy; anitomy.Parse(file); - const auto& elements = anitomy.elements(); + const auto &elements = anitomy.elements(); const std::string title = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)); @@ -136,14 +142,16 @@ playing_thread_timer_.start(5000); } -void MainWindow::SetStatusMessage(const std::string& message) { +void MainWindow::SetStatusMessage(const std::string &message) +{ statusBar()->showMessage(Strings::ToQString(message), 2000); } /* FIXME: * ALL of the pages need to have a retranslate function. This would require * huge amounts of refactoring hence why it hasn't been done yet. */ -void MainWindow::AddMainWidgets() { +void MainWindow::AddMainWidgets() +{ int page = sidebar_.GetCurrentItem(); sidebar_.clear(); @@ -164,13 +172,14 @@ main_widget_.layout()->addWidget(&stack_); } -void MainWindow::CreateBars() { - QMenuBar* menubar = new QMenuBar(this); - QAction* sync_action; +void MainWindow::CreateBars() +{ + QMenuBar *menubar = new QMenuBar(this); + QAction *sync_action; { /* File */ - QMenu* menu = menubar->addMenu(tr("&File")); + QMenu *menu = menubar->addMenu(tr("&File")); { folder_menu = menu->addMenu(tr("&Library folders")); @@ -197,14 +206,14 @@ menu->addSeparator(); { - QAction* action = menu->addAction(tr("E&xit"), this, &MainWindow::close); + QAction *action = menu->addAction(tr("E&xit"), this, &MainWindow::close); action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); } } { /* Services */ - QMenu* menu = menubar->addMenu(tr("&Services")); + QMenu *menu = menubar->addMenu(tr("&Services")); { { sync_action = menu->addAction(tr("Synchronize &list")); @@ -243,7 +252,7 @@ { /* Tools */ - QMenu* menu = menubar->addMenu(tr("&Tools")); + QMenu *menu = menubar->addMenu(tr("&Tools")); // { // /* Export anime list */ // QMenu* submenu = menu->addMenu(tr("&Export anime list")); @@ -278,7 +287,7 @@ // menu->addSeparator(); { - QAction* action = menu->addAction(tr("&Settings"), [this] { + QAction *action = menu->addAction(tr("&Settings"), [this] { SettingsDialog dialog(this); dialog.exec(); UpdateFolderMenu(); @@ -289,52 +298,52 @@ { /* View */ - QMenu* menu = menubar->addMenu(tr("&View")); + QMenu *menu = menubar->addMenu(tr("&View")); { /* Pages... */ - QActionGroup* pages_group = new QActionGroup(menu); + QActionGroup *pages_group = new QActionGroup(menu); pages_group->setExclusive(true); { - QAction* action = pages_group->addAction(menu->addAction(tr("&Now Playing"))); + QAction *action = pages_group->addAction(menu->addAction(tr("&Now Playing"))); action->setCheckable(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(0); }); } { - QAction* action = pages_group->addAction(menu->addAction(tr("&Anime List"))); + QAction *action = pages_group->addAction(menu->addAction(tr("&Anime List"))); action->setCheckable(true); action->setChecked(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(1); }); } { - QAction* action = pages_group->addAction(menu->addAction(tr("&History"))); + QAction *action = pages_group->addAction(menu->addAction(tr("&History"))); action->setCheckable(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(2); }); } { - QAction* action = pages_group->addAction(menu->addAction(tr("&Statistics"))); + QAction *action = pages_group->addAction(menu->addAction(tr("&Statistics"))); action->setCheckable(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(3); }); } { - QAction* action = pages_group->addAction(menu->addAction(tr("S&earch"))); + QAction *action = pages_group->addAction(menu->addAction(tr("S&earch"))); action->setCheckable(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(4); }); } { - QAction* action = pages_group->addAction(menu->addAction(tr("Se&asons"))); + QAction *action = pages_group->addAction(menu->addAction(tr("Se&asons"))); action->setCheckable(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(5); }); } { - QAction* action = pages_group->addAction(menu->addAction(tr("&Torrents"))); + QAction *action = pages_group->addAction(menu->addAction(tr("&Torrents"))); action->setCheckable(true); connect(action, &QAction::toggled, this, [this] { sidebar_.SetCurrentItem(6); }); } @@ -343,9 +352,9 @@ disconnect(&sidebar_, &SideBar::CurrentItemChanged, nullptr, nullptr); connect(&sidebar_, &SideBar::CurrentItemChanged, &stack_, &QStackedWidget::setCurrentIndex); connect(&sidebar_, &SideBar::CurrentItemChanged, this, [pages_group](int index) { - QAction* checked = pages_group->checkedAction(); + QAction *checked = pages_group->checkedAction(); - const QList<QAction*>& actions = pages_group->actions(); + const QList<QAction *> &actions = pages_group->actions(); if (index > actions.size()) return; @@ -364,7 +373,7 @@ { /* Help */ - QMenu* menu = menubar->addMenu(tr("&Help")); + QMenu *menu = menubar->addMenu(tr("&Help")); { /* About Minori */ @@ -376,7 +385,7 @@ { /* About Qt */ - QAction* action = menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); + QAction *action = menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); action->setMenuRole(QAction::AboutQtRole); } } @@ -389,32 +398,34 @@ /* remove old toolbar(s) */ /* the empty QString() is a Qt 5 wart... */ - for (QToolBar*& t : findChildren<QToolBar*>(QString(), Qt::FindDirectChildrenOnly)) { + for (QToolBar *&t : findChildren<QToolBar *>(QString(), Qt::FindDirectChildrenOnly)) { removeToolBar(t); delete t; } { /* Toolbar */ - QToolBar* toolbar = new QToolBar(this); + QToolBar *toolbar = new QToolBar(this); toolbar->addAction(sync_action); toolbar->addSeparator(); { - QToolButton* button = new QToolButton(toolbar); - { button->setMenu(folder_menu); } + QToolButton *button = new QToolButton(toolbar); + { + button->setMenu(folder_menu); + } button->setIcon(QIcon(":/icons/24x24/folder-open.png")); button->setPopupMode(QToolButton::InstantPopup); toolbar->addWidget(button); } { - QToolButton* button = new QToolButton(toolbar); + QToolButton *button = new QToolButton(toolbar); { /* links */ - QMenu* menu = new QMenu(button); + QMenu *menu = new QMenu(button); menu->addAction("Hibari", [] { QDesktopServices::openUrl(QUrl("https://hb.wopian.me/")); }); menu->addAction("MALgraph", [] { QDesktopServices::openUrl(QUrl("https://graph.anime.plus/")); }); menu->addSeparator(); @@ -447,7 +458,8 @@ } } -void MainWindow::UpdateFolderMenu() { +void MainWindow::UpdateFolderMenu() +{ if (!folder_menu) return; @@ -455,9 +467,9 @@ /* add in all of our existing folders... */ std::size_t i = 0; - for (const auto& path : session.config.library.paths) { + for (const auto &path : session.config.library.paths) { const QString folder = Strings::ToQString(path); - QAction* action = + QAction *action = folder_menu->addAction(folder, [folder] { QDesktopServices::openUrl(QUrl::fromLocalFile(folder)); }); if (i < 9) { @@ -487,11 +499,13 @@ } } -void MainWindow::SetActivePage(QWidget* page) { +void MainWindow::SetActivePage(QWidget *page) +{ this->setCentralWidget(page); } -void MainWindow::AsyncSynchronize(QAction* action, QStackedWidget* stack) { +void MainWindow::AsyncSynchronize(QAction *action, QStackedWidget *stack) +{ if (session.config.service == Anime::Service::None) { QMessageBox msg; msg.setWindowTitle(tr("Error synchronizing with service!")); @@ -507,7 +521,7 @@ } /* FIXME: make this use a QThread; this is *very* unsafe */ - AnimeListPage* page = reinterpret_cast<AnimeListPage*>(stack->widget(static_cast<int>(Pages::ANIME_LIST))); + AnimeListPage *page = reinterpret_cast<AnimeListPage *>(stack->widget(static_cast<int>(Pages::ANIME_LIST))); if (!async_synchronize_thread_.isRunning()) { async_synchronize_thread_.SetAction(action); async_synchronize_thread_.SetPage(page); @@ -515,7 +529,8 @@ } } -void MainWindow::RetranslateUI() { +void MainWindow::RetranslateUI() +{ /* This sucks a LOT */ setUpdatesEnabled(false); AddMainWidgets(); @@ -523,7 +538,8 @@ setUpdatesEnabled(true); } -void MainWindow::changeEvent(QEvent* event) { +void MainWindow::changeEvent(QEvent *event) +{ if (event) { /* is this really necessary */ switch (event->type()) { // this event is send if a translator is loaded @@ -535,7 +551,8 @@ QMainWindow::changeEvent(event); } -void MainWindow::showEvent(QShowEvent* event) { +void MainWindow::showEvent(QShowEvent *event) +{ QMainWindow::showEvent(event); #ifdef WIN32 /* Technically this *should* be @@ -546,7 +563,8 @@ #endif } -void MainWindow::closeEvent(QCloseEvent* event) { +void MainWindow::closeEvent(QCloseEvent *event) +{ playing_thread_timer_.stop(); playing_thread_.wait(); async_synchronize_thread_.wait();
--- a/src/library/library.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/library/library.cc Fri Jul 25 10:16:02 2025 -0400 @@ -13,7 +13,8 @@ namespace Library { -std::optional<std::filesystem::path> Database::GetAnimeFolder(int id) { +std::optional<std::filesystem::path> Database::GetAnimeFolder(int id) +{ // this function sucks, but it's the most I can really do for now. // // in the future the Refresh() function should look for directories @@ -22,11 +23,11 @@ // episodes are contained in them. whichever directory has more episodes // wins, or the first found if there is an equal amount. - for (const auto& [anime_id, episodes] : items) { + for (const auto &[anime_id, episodes] : items) { if (id != anime_id) continue; - for (const auto& [episode, path] : episodes) { + for (const auto &[episode, path] : episodes) { return path.parent_path(); break; } @@ -37,11 +38,12 @@ return std::nullopt; } -void Database::Refresh(std::optional<int> find_id) { +void Database::Refresh(std::optional<int> find_id) +{ items.clear(); - for (const auto& folder : session.config.library.paths) { - for (const auto& entry : std::filesystem::recursive_directory_iterator(folder)) { + for (const auto &folder : session.config.library.paths) { + for (const auto &entry : std::filesystem::recursive_directory_iterator(folder)) { const std::filesystem::path path = entry.path(); if (!std::filesystem::is_regular_file(path)) continue; @@ -51,7 +53,7 @@ anitomy::Anitomy anitomy; anitomy.Parse(basename); - const auto& elements = anitomy.elements(); + const auto &elements = anitomy.elements(); const std::string title = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)); @@ -59,7 +61,8 @@ if (id <= 0 || (find_id && find_id.value() != id)) continue; - const int episode = Strings::ToInt<int>(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber))); + const int episode = + Strings::ToInt<int>(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber))); // we have an ID now! items[id][episode] = path; @@ -67,11 +70,13 @@ } } -void Database::Refresh() { +void Database::Refresh() +{ Refresh(std::nullopt); } -void Database::Refresh(int id) { +void Database::Refresh(int id) +{ Refresh(std::optional<int>(id)); }
--- a/src/main.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/main.cc Fri Jul 25 10:16:02 2025 -0400 @@ -13,14 +13,15 @@ #include <cstdlib> -int main(int argc, char** argv) { +int main(int argc, char **argv) +{ QApplication app(argc, argv); app.setApplicationName("minori"); app.setApplicationDisplayName("Minori"); app.setAttribute(Qt::AA_DontShowIconsInMenus, true); qRegisterMetaType<std::vector<std::string>>(); /* window.cc */ - qRegisterMetaType<std::vector<int>>(); /* search.cc */ + qRegisterMetaType<std::vector<int>>(); /* search.cc */ qRegisterMetaType<std::string>(); qRegisterMetaType<Anime::Season>();
--- a/src/services/anilist.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/services/anilist.cc Fri Jul 25 10:16:02 2025 -0400 @@ -1,8 +1,8 @@ #include "services/anilist.h" #include "core/anime.h" #include "core/anime_db.h" +#include "core/config.h" #include "core/date.h" -#include "core/config.h" #include "core/http.h" #include "core/json.h" #include "core/session.h" @@ -70,16 +70,18 @@ /* FIXME: why is this here */ -static std::optional<nlohmann::json> SendJSONRequest(const nlohmann::json& data) { +static std::optional<nlohmann::json> SendJSONRequest(const nlohmann::json &data) +{ std::vector<std::string> headers = { - "Accept: application/json", - "Content-Type: application/json", + "Accept: application/json", + "Content-Type: application/json", }; if (!session.config.auth.anilist.auth_token.empty()) headers.push_back("Authorization: Bearer " + session.config.auth.anilist.auth_token); - const std::string response = Strings::ToUtf8String(HTTP::Request("https://graphql.anilist.co", headers, data.dump(), HTTP::Type::Post)); + const std::string response = + Strings::ToUtf8String(HTTP::Request("https://graphql.anilist.co", headers, data.dump(), HTTP::Type::Post)); if (response.empty()) { session.SetStatusBar(Strings::Translate("AniList: JSON request returned an empty result!")); return std::nullopt; @@ -89,15 +91,16 @@ try { out = nlohmann::json::parse(response); - } catch (const std::exception& ex) { - session.SetStatusBar(fmt::format(Strings::Translate("AniList: Failed to parse request JSON with error \"{}\"!"), ex.what())); + } catch (const std::exception &ex) { + session.SetStatusBar( + fmt::format(Strings::Translate("AniList: Failed to parse request JSON with error \"{}\"!"), ex.what())); return std::nullopt; } if (out.contains("/errors"_json_pointer) && out.at("/errors"_json_pointer).is_array()) { - for (const auto& error : out.at("/errors"_json_pointer)) + for (const auto &error : out.at("/errors"_json_pointer)) std::cerr << "AniList: Received an error in response: " - << JSON::GetString<std::string>(error, "/message"_json_pointer, "") << std::endl; + << JSON::GetString<std::string>(error, "/message"_json_pointer, "") << std::endl; session.SetStatusBar(Strings::Translate("AniList: Received an error in response!")); return std::nullopt; @@ -106,14 +109,15 @@ return out; } -static void ParseListStatus(std::string status, Anime::Anime& anime) { +static void ParseListStatus(std::string status, Anime::Anime &anime) +{ static const std::unordered_map<std::string, Anime::ListStatus> map = { - {"CURRENT", Anime::ListStatus::Current }, - {"PLANNING", Anime::ListStatus::Planning }, - {"COMPLETED", Anime::ListStatus::Completed}, - {"DROPPED", Anime::ListStatus::Dropped }, - {"PAUSED", Anime::ListStatus::Paused } - }; + {"CURRENT", Anime::ListStatus::Current }, + {"PLANNING", Anime::ListStatus::Planning }, + {"COMPLETED", Anime::ListStatus::Completed}, + {"DROPPED", Anime::ListStatus::Dropped }, + {"PAUSED", Anime::ListStatus::Paused } + }; if (status == "REPEATING") { anime.SetUserIsRewatching(true); @@ -129,7 +133,8 @@ anime.SetUserStatus(map.at(status)); } -static std::string ListStatusToString(const Anime::Anime& anime) { +static std::string ListStatusToString(const Anime::Anime &anime) +{ if (anime.GetUserIsRewatching() && anime.GetUserStatus() == Anime::ListStatus::Current) return "REWATCHING"; @@ -143,19 +148,21 @@ return "CURRENT"; } -static void ParseTitle(const nlohmann::json& json, Anime::Anime& anime) { +static void ParseTitle(const nlohmann::json &json, Anime::Anime &anime) +{ static const std::unordered_map<Anime::TitleLanguage, nlohmann::json::json_pointer> map = { - {Anime::TitleLanguage::Native, "/native"_json_pointer}, - {Anime::TitleLanguage::English, "/english"_json_pointer}, - {Anime::TitleLanguage::Romaji, "/romaji"_json_pointer}, + {Anime::TitleLanguage::Native, "/native"_json_pointer }, + {Anime::TitleLanguage::English, "/english"_json_pointer}, + {Anime::TitleLanguage::Romaji, "/romaji"_json_pointer }, }; - for (const auto& [language, ptr] : map) + for (const auto &[language, ptr] : map) if (json.contains(ptr) && json[ptr].is_string()) anime.SetTitle(language, json[ptr]); } -static int ParseMediaJson(const nlohmann::json& json) { +static int ParseMediaJson(const nlohmann::json &json) +{ if (!json.contains("/id"_json_pointer) || !json["/id"_json_pointer].is_number()) { session.SetStatusBar(Strings::Translate("AniList: Failed to parse anime object!")); return 0; @@ -169,7 +176,7 @@ return 0; } - Anime::Anime& anime = Anime::db.items[id]; + Anime::Anime &anime = Anime::db.items[id]; anime.SetId(id); anime.SetServiceId(Anime::Service::AniList, service_id); @@ -182,19 +189,20 @@ anime.SetFormat(Translate::AniList::ToSeriesFormat(JSON::GetString<std::string>(json, "/format"_json_pointer, ""))); anime.SetAiringStatus( - Translate::AniList::ToSeriesStatus(JSON::GetString<std::string>(json, "/status"_json_pointer, ""))); + Translate::AniList::ToSeriesStatus(JSON::GetString<std::string>(json, "/status"_json_pointer, ""))); if (json.contains("/startDate"_json_pointer) && json["/startDate"_json_pointer].is_object()) anime.SetStartedDate(Date(json["/startDate"_json_pointer])); anime.SetCompletedDate(json.contains("/endDate"_json_pointer) && json["/endDate"_json_pointer].is_object() - ? Date(json["/endDate"_json_pointer]) - : anime.GetStartedDate()); + ? Date(json["/endDate"_json_pointer]) + : anime.GetStartedDate()); anime.SetPosterUrl(JSON::GetString<std::string>(json, "/coverImage/large"_json_pointer, "")); anime.SetAudienceScore(JSON::GetNumber(json, "/averageScore"_json_pointer, 0)); - // anime.SetSeason(Translate::AniList::ToSeriesSeason(JSON::GetString<std::string>(json, "/season"_json_pointer, ""))); + // anime.SetSeason(Translate::AniList::ToSeriesSeason(JSON::GetString<std::string>(json, "/season"_json_pointer, + // ""))); anime.SetDuration(JSON::GetNumber(json, "/duration"_json_pointer, 0)); std::string synopsis = JSON::GetString<std::string>(json, "/description"_json_pointer, ""); @@ -208,7 +216,7 @@ std::vector<std::string> producers; if (json.contains("/studios/edges"_json_pointer) && json["/studios/edges"_json_pointer].is_array()) - for (const auto& edge : json["/studios/edges"_json_pointer]) + for (const auto &edge : json["/studios/edges"_json_pointer]) if (edge.contains("/node/name"_json_pointer) && edge["/node/name"_json_pointer].is_string()) producers.push_back(edge["/node/name"_json_pointer].get<std::string>()); @@ -218,12 +226,13 @@ return id; } -static int ParseListItem(const nlohmann::json& json) { +static int ParseListItem(const nlohmann::json &json) +{ int id = ParseMediaJson(json["/media"_json_pointer]); if (!id) return 0; - Anime::Anime& anime = Anime::db.items[id]; + Anime::Anime &anime = Anime::db.items[id]; anime.AddToUserList(); @@ -240,47 +249,46 @@ return id; } -static bool ParseList(const nlohmann::json& json) { +static bool ParseList(const nlohmann::json &json) +{ bool success = true; - for (const auto& entry : json["entries"].items()) + for (const auto &entry : json["entries"].items()) if (!ParseListItem(entry.value())) success = false; return success; } -int GetAnimeList() { - auto& auth = session.config.auth.anilist; +int GetAnimeList() +{ + auto &auth = session.config.auth.anilist; - static constexpr std::string_view query = - "query ($id: Int) {\n" - " MediaListCollection (userId: $id, type: ANIME) {\n" - " lists {\n" - " name\n" - " entries {\n" - " score\n" - " notes\n" - " status\n" - " progress\n" - " startedAt {\n" - " year\n" - " month\n" - " day\n" - " }\n" - " completedAt {\n" - " year\n" - " month\n" - " day\n" - " }\n" - " updatedAt\n" - " media {\n" - MEDIA_FIELDS - " }\n" - " }\n" - " }\n" - " }\n" - "}\n"; + static constexpr std::string_view query = "query ($id: Int) {\n" + " MediaListCollection (userId: $id, type: ANIME) {\n" + " lists {\n" + " name\n" + " entries {\n" + " score\n" + " notes\n" + " status\n" + " progress\n" + " startedAt {\n" + " year\n" + " month\n" + " day\n" + " }\n" + " completedAt {\n" + " year\n" + " month\n" + " day\n" + " }\n" + " updatedAt\n" + " media {\n" MEDIA_FIELDS " }\n" + " }\n" + " }\n" + " }\n" + "}\n"; // clang-format off nlohmann::json request = { @@ -299,11 +307,11 @@ Anime::db.RemoveAllUserData(); - const nlohmann::json& json = response.value(); + const nlohmann::json &json = response.value(); bool success = true; - for (const auto& list : json["data"]["MediaListCollection"]["lists"].items()) + for (const auto &list : json["data"]["MediaListCollection"]["lists"].items()) if (!ParseList(list.value())) success = false; @@ -314,15 +322,13 @@ } /* return is a vector of anime ids */ -std::vector<int> Search(const std::string& search) { - static constexpr std::string_view query = - "query ($search: String) {\n" - " Page (page: 1, perPage: 50) {\n" - " media (search: $search, type: ANIME) {\n" - MEDIA_FIELDS - " }\n" - " }\n" - "}\n"; +std::vector<int> Search(const std::string &search) +{ + static constexpr std::string_view query = "query ($search: String) {\n" + " Page (page: 1, perPage: 50) {\n" + " media (search: $search, type: ANIME) {\n" MEDIA_FIELDS " }\n" + " }\n" + "}\n"; // clang-format off nlohmann::json json = { @@ -337,55 +343,55 @@ if (!response) return {}; - const nlohmann::json& result = response.value(); + const nlohmann::json &result = response.value(); /* FIXME: error handling here */ std::vector<int> ret; ret.reserve(result["/data/Page/media"_json_pointer].size()); - for (const auto& media : result["/data/Page/media"_json_pointer].items()) + for (const auto &media : result["/data/Page/media"_json_pointer].items()) ret.push_back(ParseMediaJson(media.value())); return ret; } -bool GetSeason(Anime::Season season) { +bool GetSeason(Anime::Season season) +{ static constexpr std::string_view query = - "query ($season: MediaSeason!, $season_year: Int!, $page: Int) {\n" - " Page(page: $page) {\n" - " media(season: $season, seasonYear: $season_year, type: ANIME, sort: START_DATE) {\n" - MEDIA_FIELDS - " }\n" - " pageInfo {\n" - " total\n" - " perPage\n" - " currentPage\n" - " lastPage\n" - " hasNextPage\n" - " }\n" - " }\n" - "}\n"; + "query ($season: MediaSeason!, $season_year: Int!, $page: Int) {\n" + " Page(page: $page) {\n" + " media(season: $season, seasonYear: $season_year, type: ANIME, sort: START_DATE) {\n" MEDIA_FIELDS " }\n" + " pageInfo {\n" + " total\n" + " perPage\n" + " currentPage\n" + " lastPage\n" + " hasNextPage\n" + " }\n" + " }\n" + "}\n"; int page = 0; bool has_next_page = true; while (has_next_page) { nlohmann::json json = { - {"query", query}, - {"variables", { - {"season", Translate::AniList::ToString(season.season)}, - {"season_year", Strings::ToUtf8String(season.year)}, - {"page", page}, - }}, + {"query", query}, + {"variables", + { + {"season", Translate::AniList::ToString(season.season)}, + {"season_year", Strings::ToUtf8String(season.year)}, + {"page", page}, + } }, }; const std::optional<nlohmann::json> res = SendJSONRequest(json); if (!res) return false; - const nlohmann::json& result = res.value(); + const nlohmann::json &result = res.value(); - for (const auto& media : result["/data/Page/media"_json_pointer].items()) + for (const auto &media : result["/data/Page/media"_json_pointer].items()) ParseMediaJson(media.value()); has_next_page = JSON::GetBoolean(result, "/data/Page/pageInfo/hasNextPage"_json_pointer, false); @@ -396,8 +402,9 @@ return true; } -int UpdateAnimeEntry(int id) { - Anime::Anime& anime = Anime::db.items[id]; +int UpdateAnimeEntry(int id) +{ + Anime::Anime &anime = Anime::db.items[id]; if (!anime.IsInUserList()) return 0; @@ -406,13 +413,13 @@ return 0; static constexpr std::string_view query = - "mutation ($media_id: Int, $progress: Int, $status: MediaListStatus, $score: Int, $notes: String," - " $start: FuzzyDateInput, $comp: FuzzyDateInput, $repeat: Int) {\n" - " SaveMediaListEntry (mediaId: $media_id, progress: $progress, status: $status, scoreRaw: $score," - " notes: $notes, startedAt: $start, completedAt: $comp, repeat: $repeat) {\n" - " id\n" - " }\n" - "}\n"; + "mutation ($media_id: Int, $progress: Int, $status: MediaListStatus, $score: Int, $notes: String," + " $start: FuzzyDateInput, $comp: FuzzyDateInput, $repeat: Int) {\n" + " SaveMediaListEntry (mediaId: $media_id, progress: $progress, status: $status, scoreRaw: $score," + " notes: $notes, startedAt: $start, completedAt: $comp, repeat: $repeat) {\n" + " id\n" + " }\n" + "}\n"; // clang-format off nlohmann::json json = { {"query", query}, @@ -433,30 +440,32 @@ if (!res) return 0; - const nlohmann::json& result = res.value(); + const nlohmann::json &result = res.value(); session.SetStatusBar(Strings::Translate("AniList: Anime entry updated successfully!")); return JSON::GetNumber(result, "/data/SaveMediaListEntry/id"_json_pointer, 0); } -static int ParseUser(const nlohmann::json& json) { - auto& auth = session.config.auth.anilist; +static int ParseUser(const nlohmann::json &json) +{ + auto &auth = session.config.auth.anilist; return auth.user_id = JSON::GetNumber(json, "/id"_json_pointer, 0); } -bool AuthorizeUser() { - auto& auth = session.config.auth.anilist; +bool AuthorizeUser() +{ + auto &auth = session.config.auth.anilist; /* Prompt for PIN */ - QDesktopServices::openUrl(QUrl(Strings::ToQString("https://anilist.co/api/v2/oauth/authorize?client_id=" + - std::string(CLIENT_ID) + "&response_type=token"))); + QDesktopServices::openUrl(QUrl(Strings::ToQString( + "https://anilist.co/api/v2/oauth/authorize?client_id=" + std::string(CLIENT_ID) + "&response_type=token"))); bool ok; QString token = QInputDialog::getText( - 0, "Credentials needed!", "Please enter the code given to you after logging in to AniList:", QLineEdit::Normal, - "", &ok); + 0, "Credentials needed!", "Please enter the code given to you after logging in to AniList:", QLineEdit::Normal, + "", &ok); if (!ok || token.isEmpty()) return false; @@ -465,29 +474,28 @@ session.SetStatusBar(Strings::Translate("AniList: Requesting user ID...")); - static constexpr std::string_view query = - "query {\n" - " Viewer {\n" - " id\n" - " }\n" - "}\n"; + static constexpr std::string_view query = "query {\n" + " Viewer {\n" + " id\n" + " }\n" + "}\n"; nlohmann::json json = { - {"query", query} - }; + {"query", query} + }; /* SendJSONRequest handles status errors */ const std::optional<nlohmann::json> ret = SendJSONRequest(json); if (!ret) return 0; - const nlohmann::json& result = ret.value(); + const nlohmann::json &result = ret.value(); if (ParseUser(result["data"]["Viewer"])) session.SetStatusBar(Strings::Translate("AniList: Successfully retrieved user data!")); else session.SetStatusBar(Strings::Translate("AniList: Failed to retrieve user ID!")); - + return true; }
--- a/src/services/kitsu.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/services/kitsu.cc Fri Jul 25 10:16:02 2025 -0400 @@ -1,14 +1,14 @@ -#include "services/anilist.h" #include "core/anime.h" #include "core/anime_db.h" +#include "core/config.h" #include "core/date.h" -#include "core/config.h" #include "core/http.h" #include "core/json.h" #include "core/session.h" #include "core/strings.h" #include "core/time.h" #include "gui/translate/anilist.h" +#include "services/anilist.h" #include <QByteArray> #include <QDate> @@ -35,12 +35,12 @@ namespace Kitsu { /* This nifty little function basically handles authentication AND reauthentication. */ -static bool SendAuthRequest(const nlohmann::json& data) { - static const std::vector<std::string> headers = { - {"Content-Type: application/json"} - }; +static bool SendAuthRequest(const nlohmann::json &data) +{ + static const std::vector<std::string> headers = {{"Content-Type: application/json"}}; - const std::string ret = Strings::ToUtf8String(HTTP::Request(std::string(OAUTH_PATH), headers, data.dump(), HTTP::Type::Post)); + const std::string ret = + Strings::ToUtf8String(HTTP::Request(std::string(OAUTH_PATH), headers, data.dump(), HTTP::Type::Post)); if (ret.empty()) { session.SetStatusBar(Strings::Translate("Kitsu: Request returned empty data!")); return false; @@ -49,26 +49,23 @@ nlohmann::json result; try { result = nlohmann::json::parse(ret, nullptr, false); - } catch (const std::exception& ex) { - session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse authorization data with error \"{}\""), ex.what())); + } catch (const std::exception &ex) { + session.SetStatusBar( + fmt::format(Strings::Translate("Kitsu: Failed to parse authorization data with error \"{}\""), ex.what())); return false; } if (result.contains("/error"_json_pointer)) { - session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed with error \"{}\"!"), result["/error"_json_pointer].get<std::string>())); + session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed with error \"{}\"!"), + result["/error"_json_pointer].get<std::string>())); return false; } const std::vector<nlohmann::json::json_pointer> required = { - "/access_token"_json_pointer, - "/created_at"_json_pointer, - "/expires_in"_json_pointer, - "/refresh_token"_json_pointer, - "/scope"_json_pointer, - "/token_type"_json_pointer - }; + "/access_token"_json_pointer, "/created_at"_json_pointer, "/expires_in"_json_pointer, + "/refresh_token"_json_pointer, "/scope"_json_pointer, "/token_type"_json_pointer}; - for (const auto& ptr : required) { + for (const auto &ptr : required) { if (!result.contains(ptr)) { session.SetStatusBar(Strings::Translate("Kitsu: Authorization request returned bad data!")); return false; @@ -76,9 +73,8 @@ } session.config.auth.kitsu.access_token = result["/access_token"_json_pointer].get<std::string>(); - session.config.auth.kitsu.access_token_expiration - = result["/created_at"_json_pointer].get<Time::Timestamp>() - + result["/expires_in"_json_pointer].get<Time::Timestamp>(); + session.config.auth.kitsu.access_token_expiration = result["/created_at"_json_pointer].get<Time::Timestamp>() + + result["/expires_in"_json_pointer].get<Time::Timestamp>(); session.config.auth.kitsu.refresh_token = result["/refresh_token"_json_pointer].get<std::string>(); /* the next two are not that important */ @@ -86,10 +82,11 @@ return true; } -static bool RefreshAccessToken(void) { +static bool RefreshAccessToken(void) +{ const nlohmann::json request = { - {"grant_type", "refresh_token"}, - {"refresh_token", session.config.auth.kitsu.refresh_token}, + {"grant_type", "refresh_token" }, + {"refresh_token", session.config.auth.kitsu.refresh_token}, }; if (!SendAuthRequest(request)) @@ -100,8 +97,9 @@ /* ----------------------------------------------------------------------------- */ -static std::optional<std::string> AccountAccessToken() { - auto& auth = session.config.auth.kitsu; +static std::optional<std::string> AccountAccessToken() +{ + auto &auth = session.config.auth.kitsu; if (Time::GetSystemTime() >= session.config.auth.kitsu.access_token_expiration) if (!RefreshAccessToken()) @@ -112,20 +110,12 @@ /* ----------------------------------------------------------------------------- */ -static void AddAnimeFilters(std::map<std::string, std::string>& map) { +static void AddAnimeFilters(std::map<std::string, std::string> &map) +{ static const std::vector<std::string> fields = { - "abbreviatedTitles", - "averageRating", - "episodeCount", - "episodeLength", - "posterImage", - "startDate", - "status", - "subtype", - "titles", - "categories", - "synopsis", - "animeProductions", + "abbreviatedTitles", "averageRating", "episodeCount", "episodeLength", "posterImage", + "startDate", "status", "subtype", "titles", "categories", + "synopsis", "animeProductions", }; static const std::string imploded = Strings::Implode(fields, ","); @@ -135,18 +125,11 @@ map["fields[producers]"] = "name"; } -static void AddLibraryEntryFilters(std::map<std::string, std::string>& map) { +static void AddLibraryEntryFilters(std::map<std::string, std::string> &map) +{ static const std::vector<std::string> fields = { - "anime", - "startedAt", - "finishedAt", - "notes", - "progress", - "ratingTwenty", - "reconsumeCount", - "reconsuming", - "status", - "updatedAt", + "anime", "startedAt", "finishedAt", "notes", "progress", + "ratingTwenty", "reconsumeCount", "reconsuming", "status", "updatedAt", }; static const std::string imploded = Strings::Implode(fields, ","); @@ -155,16 +138,16 @@ /* ----------------------------------------------------------------------------- */ -static std::optional<nlohmann::json> SendJSONAPIRequest(const std::string& path, const std::map<std::string, std::string>& params = {}) { +static std::optional<nlohmann::json> SendJSONAPIRequest(const std::string &path, + const std::map<std::string, std::string> ¶ms = {}) +{ std::optional<std::string> token = AccountAccessToken(); if (!token) return std::nullopt; - const std::vector<std::string> headers = { - "Accept: application/vnd.api+json", - "Authorization: Bearer " + token.value(), - "Content-Type: application/vnd.api+json" - }; + const std::vector<std::string> headers = {"Accept: application/vnd.api+json", + "Authorization: Bearer " + token.value(), + "Content-Type: application/vnd.api+json"}; const std::string url = HTTP::EncodeParamsList(std::string(BASE_API_PATH) + path, params); @@ -175,14 +158,16 @@ nlohmann::json json; try { json = nlohmann::json::parse(response); - } catch (const std::exception& ex) { - session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse response with error \"{}\""), ex.what())); + } catch (const std::exception &ex) { + session.SetStatusBar( + fmt::format(Strings::Translate("Kitsu: Failed to parse response with error \"{}\""), ex.what())); return std::nullopt; } if (json.contains("/errors"_json_pointer)) { - for (const auto& item : json["/errors"]) - std::cerr << "Kitsu: API returned error \"" << json["/errors/title"_json_pointer] << "\" with detail \"" << json["/errors/detail"] << std::endl; + for (const auto &item : json["/errors"]) + std::cerr << "Kitsu: API returned error \"" << json["/errors/title"_json_pointer] << "\" with detail \"" + << json["/errors/detail"] << std::endl; session.SetStatusBar(Strings::Translate("Kitsu: Request failed with errors!")); return std::nullopt; @@ -191,27 +176,29 @@ return json; } -static void ParseTitleJson(Anime::Anime& anime, const nlohmann::json& json) { +static void ParseTitleJson(Anime::Anime &anime, const nlohmann::json &json) +{ static const std::map<std::string, Anime::TitleLanguage> lookup = { - {"en", Anime::TitleLanguage::English}, - {"en_jp", Anime::TitleLanguage::Romaji}, - {"ja_jp", Anime::TitleLanguage::Native} - }; + {"en", Anime::TitleLanguage::English}, + {"en_jp", Anime::TitleLanguage::Romaji }, + {"ja_jp", Anime::TitleLanguage::Native } + }; - for (const auto& [string, title] : lookup) + for (const auto &[string, title] : lookup) if (json.contains(string)) anime.SetTitle(title, json[string].get<std::string>()); } -static void ParseSubtype(Anime::Anime& anime, const std::string& str) { +static void ParseSubtype(Anime::Anime &anime, const std::string &str) +{ static const std::map<std::string, Anime::SeriesFormat> lookup = { - {"ONA", Anime::SeriesFormat::Ona}, - {"OVA", Anime::SeriesFormat::Ova}, - {"TV", Anime::SeriesFormat::Tv}, - {"movie", Anime::SeriesFormat::Movie}, - {"music", Anime::SeriesFormat::Music}, - {"special", Anime::SeriesFormat::Special} - }; + {"ONA", Anime::SeriesFormat::Ona }, + {"OVA", Anime::SeriesFormat::Ova }, + {"TV", Anime::SeriesFormat::Tv }, + {"movie", Anime::SeriesFormat::Movie }, + {"music", Anime::SeriesFormat::Music }, + {"special", Anime::SeriesFormat::Special} + }; if (lookup.find(str) == lookup.end()) return; @@ -219,14 +206,15 @@ anime.SetFormat(lookup.at(str)); } -static void ParseListStatus(Anime::Anime& anime, const std::string& str) { +static void ParseListStatus(Anime::Anime &anime, const std::string &str) +{ static const std::map<std::string, Anime::ListStatus> lookup = { - {"completed", Anime::ListStatus::Completed}, - {"current", Anime::ListStatus::Current}, - {"dropped", Anime::ListStatus::Dropped}, - {"on_hold", Anime::ListStatus::Paused}, - {"planned", Anime::ListStatus::Planning} - }; + {"completed", Anime::ListStatus::Completed}, + {"current", Anime::ListStatus::Current }, + {"dropped", Anime::ListStatus::Dropped }, + {"on_hold", Anime::ListStatus::Paused }, + {"planned", Anime::ListStatus::Planning } + }; if (lookup.find(str) == lookup.end()) return; @@ -234,13 +222,14 @@ anime.SetUserStatus(lookup.at(str)); } -static void ParseSeriesStatus(Anime::Anime& anime, const std::string& str) { +static void ParseSeriesStatus(Anime::Anime &anime, const std::string &str) +{ static const std::map<std::string, Anime::SeriesStatus> lookup = { - {"current", Anime::SeriesStatus::Releasing}, - {"finished", Anime::SeriesStatus::Finished}, - {"tba", Anime::SeriesStatus::Hiatus}, // is this right? - {"unreleased", Anime::SeriesStatus::Cancelled}, - {"upcoming", Anime::SeriesStatus::NotYetReleased}, + {"current", Anime::SeriesStatus::Releasing }, + {"finished", Anime::SeriesStatus::Finished }, + {"tba", Anime::SeriesStatus::Hiatus }, // is this right? + {"unreleased", Anime::SeriesStatus::Cancelled }, + {"upcoming", Anime::SeriesStatus::NotYetReleased}, }; if (lookup.find(str) == lookup.end()) @@ -249,7 +238,8 @@ anime.SetAiringStatus(lookup.at(str)); } -static int ParseAnimeJson(const nlohmann::json& json) { +static int ParseAnimeJson(const nlohmann::json &json) +{ const std::string FAILED_TO_PARSE = Strings::Translate("Kitsu: Failed to parse anime object! {}"); const std::string service_id = json["/id"_json_pointer].get<std::string>(); @@ -263,11 +253,11 @@ return 0; } - const auto& attributes = json["/attributes"_json_pointer]; + const auto &attributes = json["/attributes"_json_pointer]; int id = Anime::db.LookupServiceIdOrUnused(Anime::Service::Kitsu, service_id); - Anime::Anime& anime = Anime::db.items[id]; + Anime::Anime &anime = Anime::db.items[id]; anime.SetId(id); anime.SetServiceId(Anime::Service::Kitsu, service_id); @@ -278,8 +268,9 @@ if (attributes.contains("/titles"_json_pointer) && attributes["/titles"_json_pointer].is_object()) ParseTitleJson(anime, attributes["/titles"_json_pointer]); - if (attributes.contains("/abbreviatedTitles"_json_pointer) && attributes["/abbreviatedTitles"_json_pointer].is_array()) - for (const auto& title : attributes["/abbreviatedTitles"_json_pointer]) + if (attributes.contains("/abbreviatedTitles"_json_pointer) && + attributes["/abbreviatedTitles"_json_pointer].is_array()) + for (const auto &title : attributes["/abbreviatedTitles"_json_pointer]) anime.AddTitleSynonym(title.get<std::string>()); if (attributes.contains("/averageRating"_json_pointer) && attributes["/averageRating"_json_pointer].is_string()) @@ -288,9 +279,10 @@ if (attributes.contains("/startDate"_json_pointer) && attributes["/startDate"_json_pointer].is_string()) anime.SetStartedDate(attributes["/startDate"_json_pointer].get<std::string>()); - anime.SetCompletedDate(attributes.contains("/endDate"_json_pointer) && attributes["/endDate"_json_pointer].is_string() - ? attributes["/endDate"_json_pointer].get<std::string>() - : anime.GetStartedDate()); + anime.SetCompletedDate(attributes.contains("/endDate"_json_pointer) && + attributes["/endDate"_json_pointer].is_string() + ? attributes["/endDate"_json_pointer].get<std::string>() + : anime.GetStartedDate()); if (attributes.contains("/subtype"_json_pointer) && attributes["/subtype"_json_pointer].is_string()) ParseSubtype(anime, attributes["/subtype"_json_pointer].get<std::string>()); @@ -298,7 +290,8 @@ if (attributes.contains("/status"_json_pointer) && attributes["/status"_json_pointer].is_string()) ParseSeriesStatus(anime, attributes["/status"_json_pointer].get<std::string>()); - if (attributes.contains("/posterImage/original"_json_pointer) && attributes["/posterImage/original"_json_pointer].is_string()) + if (attributes.contains("/posterImage/original"_json_pointer) && + attributes["/posterImage/original"_json_pointer].is_string()) anime.SetPosterUrl(attributes["/posterImage/original"_json_pointer].get<std::string>()); if (attributes.contains("/episodeCount"_json_pointer) && attributes["/episodeCount"_json_pointer].is_number()) @@ -310,16 +303,18 @@ return id; } -static int ParseLibraryJson(const nlohmann::json& json) { +static int ParseLibraryJson(const nlohmann::json &json) +{ static const std::vector<nlohmann::json::json_pointer> required = { - "/id"_json_pointer, - "/relationships/anime/data/id"_json_pointer, - "/attributes"_json_pointer, + "/id"_json_pointer, + "/relationships/anime/data/id"_json_pointer, + "/attributes"_json_pointer, }; - for (const auto& ptr : required) { + for (const auto &ptr : required) { if (!json.contains(ptr)) { - session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse library object! (missing {})"), ptr.to_string())); + session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to parse library object! (missing {})"), + ptr.to_string())); return 0; } } @@ -332,11 +327,11 @@ int id = Anime::db.LookupServiceIdOrUnused(Anime::Service::Kitsu, service_id); - const auto& attributes = json["/attributes"_json_pointer]; + const auto &attributes = json["/attributes"_json_pointer]; const std::string library_id = json["/id"_json_pointer].get<std::string>(); - Anime::Anime& anime = Anime::db.items[id]; + Anime::Anime &anime = Anime::db.items[id]; anime.AddToUserList(); @@ -346,10 +341,12 @@ anime.SetUserId(library_id); if (attributes.contains("/startedAt"_json_pointer) && attributes["/startedAt"_json_pointer].is_string()) - anime.SetUserDateStarted(Date(Time::ParseISO8601Time(attributes["/startedAt"_json_pointer].get<std::string>()))); + anime.SetUserDateStarted( + Date(Time::ParseISO8601Time(attributes["/startedAt"_json_pointer].get<std::string>()))); if (attributes.contains("/finishedAt"_json_pointer) && attributes["/finishedAt"_json_pointer].is_string()) - anime.SetUserDateCompleted(Date(Time::ParseISO8601Time(attributes["/finishedAt"_json_pointer].get<std::string>()))); + anime.SetUserDateCompleted( + Date(Time::ParseISO8601Time(attributes["/finishedAt"_json_pointer].get<std::string>()))); if (attributes.contains("/notes"_json_pointer) && attributes["/notes"_json_pointer].is_string()) anime.SetUserNotes(attributes["/notes"_json_pointer].get<std::string>()); @@ -378,11 +375,12 @@ return id; } -static void ParseMetadataJson(Anime::Anime& anime, const nlohmann::json& json) { +static void ParseMetadataJson(Anime::Anime &anime, const nlohmann::json &json) +{ std::vector<std::string> categories; std::vector<std::string> producers; - for (const auto& item : json) { + for (const auto &item : json) { std::string variant; { static const nlohmann::json::json_pointer p = "/type"_json_pointer; @@ -415,10 +413,12 @@ anime.SetProducers(producers); } -static bool ParseAnyJson(const nlohmann::json& json) { +static bool ParseAnyJson(const nlohmann::json &json) +{ static const nlohmann::json::json_pointer required = "/type"_json_pointer; if (!json.contains(required) && !json[required].is_string()) { - session.SetStatusBar(fmt::format(Strings::Translate("Kitsu: Failed to generic object! (missing {})"), required.to_string())); + session.SetStatusBar( + fmt::format(Strings::Translate("Kitsu: Failed to generic object! (missing {})"), required.to_string())); return 0; } @@ -437,10 +437,11 @@ return true; } -int GetAnimeList() { +int GetAnimeList() +{ static constexpr int LIBRARY_MAX_SIZE = 500; - const auto& auth = session.config.auth.kitsu; + const auto &auth = session.config.auth.kitsu; if (auth.user_id.empty()) { session.SetStatusBar(Strings::Translate("Kitsu: User ID is unavailable!")); @@ -451,12 +452,12 @@ bool have_next_page = true; std::map<std::string, std::string> params = { - {"filter[user_id]", auth.user_id}, - {"filter[kind]", "anime"}, - {"include", "anime"}, - {"page[offset]", Strings::ToUtf8String(page)}, - {"page[limit]", Strings::ToUtf8String(LIBRARY_MAX_SIZE)} - }; + {"filter[user_id]", auth.user_id }, + {"filter[kind]", "anime" }, + {"include", "anime" }, + {"page[offset]", Strings::ToUtf8String(page) }, + {"page[limit]", Strings::ToUtf8String(LIBRARY_MAX_SIZE)} + }; AddAnimeFilters(params); AddLibraryEntryFilters(params); @@ -469,19 +470,20 @@ if (!response) return 0; - const nlohmann::json& root = response.value(); + const nlohmann::json &root = response.value(); if (root.contains("/next"_json_pointer) && root["/next"_json_pointer].is_number()) { page += root["/next"_json_pointer].get<int>(); if (page <= 0) have_next_page = false; - } else have_next_page = false; + } else + have_next_page = false; - for (const auto& item : root["/data"_json_pointer]) + for (const auto &item : root["/data"_json_pointer]) if (!ParseLibraryJson(item)) success = false; - for (const auto& variant : root["/included"_json_pointer]) + for (const auto &variant : root["/included"_json_pointer]) if (!ParseAnyJson(variant)) success = false; @@ -494,9 +496,10 @@ return 1; } -bool RetrieveAnimeMetadata(int id) { +bool RetrieveAnimeMetadata(int id) +{ /* TODO: the genres should *probably* be a std::optional */ - Anime::Anime& anime = Anime::db.items[id]; + Anime::Anime &anime = Anime::db.items[id]; if (anime.GetGenres().size() > 0 && anime.GetProducers().size()) return false; @@ -507,21 +510,23 @@ session.SetStatusBar(Strings::Translate("Kitsu: Retrieving anime metadata...")); static const std::map<std::string, std::string> params = { - {"include", Strings::Implode({ - "categories", - "animeProductions", - "animeProductions.producer", - }, ",")} - }; + {"include", Strings::Implode( + { + "categories", + "animeProductions", + "animeProductions.producer", + }, ",")} + }; std::optional<nlohmann::json> response = SendJSONAPIRequest("/anime/" + service_id.value(), params); if (!response) return false; - const auto& json = response.value(); + const auto &json = response.value(); if (!json.contains("/included"_json_pointer) || !json["/included"_json_pointer].is_array()) { - session.SetStatusBar(Strings::Translate("Kitsu: Server returned bad data when trying to retrieve anime metadata!")); + session.SetStatusBar( + Strings::Translate("Kitsu: Server returned bad data when trying to retrieve anime metadata!")); return false; } @@ -533,37 +538,41 @@ } /* unimplemented for now */ -std::vector<int> Search(const std::string& search) { +std::vector<int> Search(const std::string &search) +{ return {}; } -bool GetSeason(Anime::Season season) { +bool GetSeason(Anime::Season season) +{ return false; } -int UpdateAnimeEntry(int id) { +int UpdateAnimeEntry(int id) +{ return 0; } -bool AuthorizeUser(const std::string& email, const std::string& password) { +bool AuthorizeUser(const std::string &email, const std::string &password) +{ const nlohmann::json body = { - {"grant_type", "password"}, - {"username", email}, - {"password", HTTP::UrlEncode(password)} - }; + {"grant_type", "password" }, + {"username", email }, + {"password", HTTP::UrlEncode(password)} + }; if (!SendAuthRequest(body)) return false; static const std::map<std::string, std::string> params = { - {"filter[self]", "true"} - }; + {"filter[self]", "true"} + }; std::optional<nlohmann::json> response = SendJSONAPIRequest("/users", params); if (!response) return false; // whuh? - const nlohmann::json& json = response.value(); + const nlohmann::json &json = response.value(); if (!json.contains("/data/0/id"_json_pointer)) { session.SetStatusBar(Strings::Translate("Kitsu: Failed to retrieve user ID!"));
--- a/src/services/services.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/services/services.cc Fri Jul 25 10:16:02 2025 -0400 @@ -9,8 +9,10 @@ namespace Services { -void Synchronize() { - session.SetStatusBar(fmt::format(Strings::Translate("{}: Retrieving anime list..."), Translate::ToString(session.config.service))); +void Synchronize() +{ + session.SetStatusBar( + fmt::format(Strings::Translate("{}: Retrieving anime list..."), Translate::ToString(session.config.service))); switch (session.config.service) { case Anime::Service::AniList: AniList::GetAnimeList(); break; @@ -19,15 +21,18 @@ } } -bool RetrieveAnimeMetadata(int id) { +bool RetrieveAnimeMetadata(int id) +{ switch (session.config.service) { - case Anime::Service::Kitsu: return Kitsu::RetrieveAnimeMetadata(id); + case Anime::Service::Kitsu: return Kitsu::RetrieveAnimeMetadata(id); default: return false; } } -std::vector<int> Search(const std::string& search) { - session.SetStatusBar(fmt::format(Strings::Translate("{}: Requesting search query..."), Translate::ToString(session.config.service))); +std::vector<int> Search(const std::string &search) +{ + session.SetStatusBar( + fmt::format(Strings::Translate("{}: Requesting search query..."), Translate::ToString(session.config.service))); switch (session.config.service) { case Anime::Service::AniList: return AniList::Search(search); @@ -36,8 +41,10 @@ } } -bool GetSeason(Anime::Season season) { - session.SetStatusBar(fmt::format(Strings::Translate("{}: Retrieving anime season data..."), Translate::ToString(session.config.service))); +bool GetSeason(Anime::Season season) +{ + session.SetStatusBar(fmt::format(Strings::Translate("{}: Retrieving anime season data..."), + Translate::ToString(session.config.service))); switch (session.config.service) { case Anime::Service::AniList: return AniList::GetSeason(season); @@ -46,8 +53,10 @@ } } -void UpdateAnimeEntry(int id) { - session.SetStatusBar(fmt::format(Strings::Translate("{}: Updating remote anime entry..."), Translate::ToString(session.config.service))); +void UpdateAnimeEntry(int id) +{ + session.SetStatusBar(fmt::format(Strings::Translate("{}: Updating remote anime entry..."), + Translate::ToString(session.config.service))); switch (session.config.service) { case Anime::Service::AniList: AniList::UpdateAnimeEntry(id); break;
--- a/src/track/media.cc Fri Jul 25 10:05:23 2025 -0400 +++ b/src/track/media.cc Fri Jul 25 10:16:02 2025 -0400 @@ -18,11 +18,12 @@ namespace Track { namespace Media { -static bool GetCurrentlyPlayingResults(std::vector<animone::Result>& results) { +static bool GetCurrentlyPlayingResults(std::vector<animone::Result> &results) +{ std::vector<animone::Player> players; players.reserve(session.config.recognition.players.size()); - for (const auto& [enabled, player] : session.config.recognition.players) + for (const auto &[enabled, player] : session.config.recognition.players) if (enabled && player.type == animone::PlayerType::Default) players.push_back(player); @@ -34,7 +35,8 @@ * standard. However, window titles are not, and for some obscure X11 * window managers, WILL not be in UTF-8. I don't care enough about this * to do anything about it though. */ -bool GetCurrentlyPlaying(std::vector<std::string>& vec) { +bool GetCurrentlyPlaying(std::vector<std::string> &vec) +{ std::vector<animone::Result> results; if (!GetCurrentlyPlayingResults(results)) @@ -42,9 +44,9 @@ bool success = false; - for (const auto& result : results) { - for (const auto& media : result.media) { - for (const auto& info : media.information) { + for (const auto &result : results) { + for (const auto &media : result.media) { + for (const auto &info : media.information) { switch (info.type) { case animone::MediaInfoType::File: vec.push_back(std::filesystem::path(info.value).filename().u8string()); @@ -54,10 +56,8 @@ vec.push_back(info.value); success |= true; break; - case animone::MediaInfoType::Tab: - break; - case animone::MediaInfoType::Url: - break; + case animone::MediaInfoType::Tab: break; + case animone::MediaInfoType::Url: break; default: break; } }