# HG changeset patch
# User Paper
# Date 1712188118 14400
# Node ID dd211ff68b36fb727b849fa1238844f573b9bcc7
# Parent 0362f3c4534c5d268af1d330f764e6d9b6dd6466
pages/seasons: add initial functionality
the menu doesn't work yet, but it's a good start
diff -r 0362f3c4534c -r dd211ff68b36 Makefile.am
--- a/Makefile.am Mon Apr 01 18:11:15 2024 -0400
+++ b/Makefile.am Wed Apr 03 19:48:38 2024 -0400
@@ -154,6 +154,7 @@
noinst_HEADERS = \
include/core/anime_db.h \
include/core/anime.h \
+ include/core/anime_season_db.h \
include/core/config.h \
include/core/date.h \
include/core/filesystem.h \
@@ -180,6 +181,7 @@
minori_SOURCES = \
src/core/anime_db.cc \
src/core/anime.cc \
+ src/core/anime_season_db.cc \
src/core/config.cc \
src/core/date.cc \
src/core/filesystem.cc \
diff -r 0362f3c4534c -r dd211ff68b36 include/core/anime.h
--- a/include/core/anime.h Mon Apr 01 18:11:15 2024 -0400
+++ b/include/core/anime.h Wed Apr 03 19:48:38 2024 -0400
@@ -50,6 +50,11 @@
FALL
};
+constexpr std::array SeriesSeasons{
+ SeriesSeason::WINTER, SeriesSeason::SPRING,
+ SeriesSeason::SUMMER, SeriesSeason::FALL
+};
+
enum class TitleLanguage {
ROMAJI,
NATIVE,
diff -r 0362f3c4534c -r dd211ff68b36 include/core/anime_season_db.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/core/anime_season_db.h Wed Apr 03 19:48:38 2024 -0400
@@ -0,0 +1,13 @@
+#ifndef MINORI_CORE_ANIME_SEASON_DB_H_
+#define MINORI_CORE_ANIME_SEASON_DB_H_
+
+#include "core/anime.h"
+#include "core/date.h"
+
+namespace Anime::Season {
+
+std::vector GetAllAnimeForSeason(SeriesSeason season, Date::Year year);
+
+}
+
+#endif // MINORI_CORE_ANIME_SEASON_DB_H_
diff -r 0362f3c4534c -r dd211ff68b36 include/core/strings.h
--- a/include/core/strings.h Mon Apr 01 18:11:15 2024 -0400
+++ b/include/core/strings.h Wed Apr 03 19:48:38 2024 -0400
@@ -21,13 +21,13 @@
std::vector Split(const std::string& text, const std::string& delimiter);
/* Substring removal functions */
-std::string ReplaceAll(std::string string, const std::string& find, const std::string& replace);
-std::string SanitizeLineEndings(const std::string& string);
-std::string RemoveHtmlTags(std::string string);
-std::string ParseHtmlEntities(std::string string);
+void ReplaceAll(std::string& string, std::string_view find, std::string_view replace);
+void SanitizeLineEndings(std::string& string);
+void RemoveHtmlTags(std::string& string);
+void ParseHtmlEntities(std::string& string);
/* stupid HTML bullshit */
-std::string TextifySynopsis(const std::string& string);
+void TextifySynopsis(std::string& string);
std::string ToUpper(const std::string& string);
std::string ToLower(const std::string& string);
diff -r 0362f3c4534c -r dd211ff68b36 include/gui/pages/seasons.h
--- a/include/gui/pages/seasons.h Mon Apr 01 18:11:15 2024 -0400
+++ b/include/gui/pages/seasons.h Wed Apr 03 19:48:38 2024 -0400
@@ -3,6 +3,9 @@
#include
+#include "core/anime.h"
+#include "core/date.h"
+
class QListWidget;
class QResizeEvent;
@@ -11,6 +14,7 @@
public:
SeasonsPage(QWidget* parent = nullptr);
+ void SetSeason(Anime::SeriesSeason season, Date::Year year);
protected:
QListWidget* buttons = nullptr;
diff -r 0362f3c4534c -r dd211ff68b36 src/core/anime_db.cc
--- a/src/core/anime_db.cc Mon Apr 01 18:11:15 2024 -0400
+++ b/src/core/anime_db.cc Wed Apr 03 19:48:38 2024 -0400
@@ -131,12 +131,14 @@
return 0;
for (const auto& [id, anime] : items) {
- if (anime.GetUserPreferredTitle() == title)
- return id;
+ std::vector synonyms(anime.GetTitleSynonyms());
+ synonyms.push_back(anime.GetUserPreferredTitle());
- for (const auto& synonym : anime.GetTitleSynonyms())
- if (synonym == title)
+ for (const auto& synonym : synonyms) {
+ if (synonym == title) {
return id;
+ }
+ }
}
return 0;
diff -r 0362f3c4534c -r dd211ff68b36 src/core/anime_season_db.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/anime_season_db.cc Wed Apr 03 19:48:38 2024 -0400
@@ -0,0 +1,20 @@
+#include "core/anime_season_db.h"
+#include "core/anime.h"
+#include "core/anime_db.h"
+#include "core/date.h"
+
+namespace Anime::Season {
+
+std::vector GetAllAnimeForSeason(SeriesSeason season, Date::Year year) {
+ std::vector ret;
+
+ for (const auto& [id, anime] : db.items) {
+ std::optional anime_year = anime.GetAirDate().GetYear();
+ if (anime.GetSeason() == season && anime_year && anime_year.value() == year)
+ ret.push_back(id);
+ }
+
+ return ret;
+}
+
+}
diff -r 0362f3c4534c -r dd211ff68b36 src/core/strings.cc
--- a/src/core/strings.cc Mon Apr 01 18:11:15 2024 -0400
+++ b/src/core/strings.cc Wed Apr 03 19:48:38 2024 -0400
@@ -70,26 +70,38 @@
/* This function is really only used for cleaning up the synopsis of
* horrible HTML debris from AniList :)
*/
-std::string ReplaceAll(std::string string, const std::string& find, const std::string& 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);
pos += replace.length();
}
- return string;
}
-std::string SanitizeLineEndings(const std::string& string) {
+void SanitizeLineEndings(std::string& string) {
/* LOL */
- return ReplaceAll(ReplaceAll(ReplaceAll(ReplaceAll(ReplaceAll(string, "\r\n", "\n"), "
", "\n"), "
", "\n"),
- "
", "\n"),
- "\n\n\n", "\n\n");
+ ReplaceAll(string, "\r\n", "\n");
+ ReplaceAll(string, "", "\n");
+ ReplaceAll(string, "
", "\n");
+ ReplaceAll(string, "
", "\n");
+ ReplaceAll(string, "\n\n\n", "\n\n");
+}
+
+void ConvertRomanNumerals(std::string& string) {
+ static const std::vector> vec = {
+ {"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)
+ ReplaceAll(string, item.second, item.first);
}
/* removes dumb HTML tags because anilist is aids and
* gives us HTML for synopses :/
*/
-std::string RemoveHtmlTags(std::string string) {
+void RemoveHtmlTags(std::string& string) {
while (string.find("<") != std::string::npos) {
auto startpos = string.find("<");
auto endpos = string.find(">") + 1;
@@ -97,17 +109,16 @@
if (endpos != std::string::npos)
string.erase(startpos, endpos - startpos);
}
- return string;
}
/* e.g. "<" for "<" */
-std::string ParseHtmlEntities(std::string string) {
+void ParseHtmlEntities(std::string& string) {
+ /* The only one of these I can understand using are the first
+ * three. why do the rest of these exist?
+ *
+ * probably mojibake.
+ */
const std::unordered_map map = {
- /* The only one of these I can understand using are the first
- * three. why do the rest of these exist?
- *
- * probably mojibake.
- */
{"<", "<" },
{"&rt;", ">" },
{" ", "\xA0"},
@@ -124,13 +135,14 @@
};
for (const auto& item : map)
- string = ReplaceAll(string, item.first, item.second);
- return string;
+ ReplaceAll(string, item.first, item.second);
}
/* removes stupid HTML stuff */
-std::string TextifySynopsis(const std::string& string) {
- return ParseHtmlEntities(RemoveHtmlTags(SanitizeLineEndings(string)));
+void TextifySynopsis(std::string& string) {
+ SanitizeLineEndings(string);
+ RemoveHtmlTags(string);
+ ParseHtmlEntities(string);
}
/* let Qt handle the heavy lifting of locale shit
diff -r 0362f3c4534c -r dd211ff68b36 src/gui/pages/seasons.cc
--- a/src/gui/pages/seasons.cc Mon Apr 01 18:11:15 2024 -0400
+++ b/src/gui/pages/seasons.cc Wed Apr 03 19:48:38 2024 -0400
@@ -1,8 +1,12 @@
#include "gui/pages/seasons.h"
#include "core/anime_db.h"
+#include "core/anime_season_db.h"
+#include "core/strings.h"
#include "gui/widgets/anime_button.h"
+#include "gui/translate/anime.h"
+#include
#include
#include
#include
@@ -11,6 +15,23 @@
#include
#include
+static constexpr Date::Year GetClosestDecade(Date::Year year) {
+ return year - (year % 10);
+}
+
+void SeasonsPage::SetSeason(Anime::SeriesSeason season, Date::Year year) {
+ buttons->clear();
+
+ for (const auto& id : Anime::Season::GetAllAnimeForSeason(season, year)) {
+ QListWidgetItem* item = new QListWidgetItem;
+ AnimeButton* button = new AnimeButton(this);
+ button->SetAnime(Anime::db.items[id]);
+ item->setSizeHint(button->sizeHint());
+ buttons->addItem(item);
+ buttons->setItemWidget(item, button);
+ }
+}
+
SeasonsPage::SeasonsPage(QWidget* parent) : QWidget(parent) {
QVBoxLayout* full_layout = new QVBoxLayout(this);
@@ -22,22 +43,44 @@
toolbar->setMovable(false);
{
- {
- QAction* action = new QAction(toolbar);
- action->setIcon(QIcon(":/icons/16x16/calendar-previous.png"));
- action->setToolTip(tr("Previous season"));
- toolbar->addAction(action);
- }
+ /* hard-coded this value */
+ static constexpr Date::Year last_year = 1960;
+
+ auto create_year_menu = [](QWidget* parent, QMenu* parent_menu, Date::Year year){
+ const QString year_s = QString::number(year);
+
+ QMenu* menu = new QMenu(year_s, parent);
+ for (const auto& season : Anime::SeriesSeasons)
+ menu->addAction(Strings::ToQString(Translate::ToLocalString(season)) + " " + year_s);
+ parent_menu->addMenu(menu);
+ };
+
+ auto create_decade_menu = [create_year_menu](QWidget* parent, QMenu* parent_menu, Date::Year decade) {
+ QMenu* menu = new QMenu(QString::number(decade) + "s", parent);
+ for (int i = 9; i >= 0; i--)
+ create_year_menu(parent, menu, decade + i);
+ parent_menu->addMenu(menu);
+ };
- {
- QAction* action = new QAction(toolbar);
- action->setIcon(QIcon(":/icons/16x16/calendar-next.png"));
- action->setToolTip(tr("Next season"));
- toolbar->addAction(action);
- }
+ /* we'll be extinct by the time this code breaks, so I guess it's fine :) */
+ const Date::Year year = static_cast(QDate::currentDate().year());
+ const Date::Year year_before_collapse = GetClosestDecade(year) - 10;
+ QToolButton* season_button = new QToolButton(toolbar);
+ QMenu* full_season_menu = new QMenu(season_button);
+
+ for (Date::Year c = year; c >= year_before_collapse; c--)
+ create_year_menu(season_button, full_season_menu, c);
- toolbar->addAction(QIcon(":/icons/16x16/calendar.png"),
- "Fall 2024"); // this must be named the name of the season
+ full_season_menu->addSeparator();
+
+ for (Date::Year c = year_before_collapse - 10; c >= last_year; c -= 10)
+ create_decade_menu(season_button, full_season_menu, c);
+
+ season_button->setMenu(full_season_menu);
+ season_button->setText("Summer 2011");
+ season_button->setPopupMode(QToolButton::InstantPopup);
+
+ toolbar->addWidget(season_button);
}
toolbar->addSeparator();
@@ -123,39 +166,9 @@
buttons->setSpacing(2);
buttons->setResizeMode(QListView::Adjust);
- {
- QListWidgetItem* item = new QListWidgetItem;
- AnimeButton* button = new AnimeButton(this);
- button->SetAnime(Anime::db.items[Anime::db.GetAnimeFromTitle("Another")]);
- item->setSizeHint(button->sizeHint());
- buttons->addItem(item);
- buttons->setItemWidget(item, button);
- }
- {
- QListWidgetItem* item = new QListWidgetItem;
- AnimeButton* button = new AnimeButton(this);
- button->SetAnime(Anime::db.items[Anime::db.GetAnimeFromTitle("Another")]);
- item->setSizeHint(button->sizeHint());
- buttons->addItem(item);
- buttons->setItemWidget(item, button);
- }
- {
- QListWidgetItem* item = new QListWidgetItem;
- AnimeButton* button = new AnimeButton(this);
- button->SetAnime(Anime::db.items[Anime::db.GetAnimeFromTitle("Another")]);
- item->setSizeHint(button->sizeHint());
- buttons->addItem(item);
- buttons->setItemWidget(item, button);
- }
- {
- QListWidgetItem* item = new QListWidgetItem;
- AnimeButton* button = new AnimeButton(this);
- button->SetAnime(Anime::db.items[Anime::db.GetAnimeFromTitle("Another")]);
- item->setSizeHint(button->sizeHint());
- buttons->addItem(item);
- buttons->setItemWidget(item, button);
- }
-
full_layout->addWidget(buttons);
}
+
+ /* Do NOT move this up in this function, buttons HAS to be initialized */
+ SetSeason(Anime::SeriesSeason::SUMMER, 2011);
}
diff -r 0362f3c4534c -r dd211ff68b36 src/gui/pages/torrents.cc
--- a/src/gui/pages/torrents.cc Mon Apr 01 18:11:15 2024 -0400
+++ b/src/gui/pages/torrents.cc Wed Apr 03 19:48:38 2024 -0400
@@ -157,7 +157,9 @@
torrent.SetResolution(Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution)));
}
- ParseFeedDescription(Strings::TextifySynopsis(item.child_value("description")), torrent);
+ std::string description = item.child_value("description");
+ Strings::TextifySynopsis(description);
+ ParseFeedDescription(description, torrent);
torrent.SetLink(item.child_value("link"));
torrent.SetGuid(item.child_value("guid"));
diff -r 0362f3c4534c -r dd211ff68b36 src/services/anilist.cc
--- a/src/services/anilist.cc Mon Apr 01 18:11:15 2024 -0400
+++ b/src/services/anilist.cc Wed Apr 03 19:48:38 2024 -0400
@@ -138,7 +138,10 @@
anime.SetAudienceScore(JSON::GetNumber(json, "/averageScore"_json_pointer, 0));
anime.SetSeason(Translate::AniList::ToSeriesSeason(JSON::GetString(json, "/season"_json_pointer, "")));
anime.SetDuration(JSON::GetNumber(json, "/duration"_json_pointer, 0));
- anime.SetSynopsis(Strings::TextifySynopsis(JSON::GetString(json, "/description"_json_pointer, "")));
+
+ std::string synopsis = JSON::GetString(json, "/description"_json_pointer, "");
+ Strings::TextifySynopsis(synopsis);
+ anime.SetSynopsis(synopsis);
anime.SetGenres(JSON::GetArray>(json, "/genres"_json_pointer, {}));
anime.SetTitleSynonyms(JSON::GetArray>(json, "/synonyms"_json_pointer, {}));