changeset 304:2115488eb302

*: add very early season searcher
author Paper <paper@paper.us.eu.org>
date Mon, 13 May 2024 17:02:35 -0400
parents ab7ff259b4ca
children 91ac90a34003
files include/gui/translate/anilist.h include/services/anilist.h include/services/services.h src/gui/pages/seasons.cc src/gui/translate/anilist.cc src/services/anilist.cc src/services/services.cc
diffstat 7 files changed, 107 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/include/gui/translate/anilist.h	Mon May 13 15:19:55 2024 -0400
+++ b/include/gui/translate/anilist.h	Mon May 13 17:02:35 2024 -0400
@@ -9,6 +9,7 @@
 Anime::SeriesStatus ToSeriesStatus(const std::string& status);
 Anime::SeriesSeason ToSeriesSeason(const std::string& season);
 Anime::SeriesFormat ToSeriesFormat(const std::string& format);
+std::string ToString(Anime::SeriesSeason season);
 
 } // namespace AniList
 } // namespace Translate
--- a/include/services/anilist.h	Mon May 13 15:19:55 2024 -0400
+++ b/include/services/anilist.h	Mon May 13 17:02:35 2024 -0400
@@ -1,6 +1,9 @@
 #ifndef MINORI_SERVICES_ANILIST_H_
 #define MINORI_SERVICES_ANILIST_H_
 
+#include "core/anime.h"
+#include "core/date.h"
+
 #include <string>
 #include <vector>
 
@@ -14,6 +17,7 @@
 
 /* Search query */
 std::vector<int> Search(const std::string& search);
+std::vector<int> GetSeason(Anime::SeriesSeason season, Date::Year year);
 
 /* Write queries (mutations) */
 int UpdateAnimeEntry(int id);
--- a/include/services/services.h	Mon May 13 15:19:55 2024 -0400
+++ b/include/services/services.h	Mon May 13 17:02:35 2024 -0400
@@ -1,6 +1,9 @@
 #ifndef MINORI_SERVICES_SERVICES_H_
 #define MINORI_SERVICES_SERVICES_H_
 
+#include "core/anime.h"
+#include "core/date.h"
+
 #include <string>
 #include <vector>
 
@@ -8,6 +11,7 @@
 
 void Synchronize();
 std::vector<int> Search(const std::string& search);
+std::vector<int> GetSeason(Anime::SeriesSeason season, Date::Year year);
 void UpdateAnimeEntry(int id);
 bool Authorize();
 
--- a/src/gui/pages/seasons.cc	Mon May 13 15:19:55 2024 -0400
+++ b/src/gui/pages/seasons.cc	Mon May 13 17:02:35 2024 -0400
@@ -5,6 +5,7 @@
 #include "core/strings.h"
 #include "gui/widgets/anime_button.h"
 #include "gui/translate/anime.h"
+#include "services/services.h"
 
 #include <QDate>
 #include <QFrame>
@@ -97,7 +98,12 @@
 
 		toolbar->addSeparator();
 
-		{ toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("Refresh data")); }
+		{
+			toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("Refresh data"), [this]{
+				Services::GetSeason(Anime::SeriesSeason::Summer, 2011U);
+				SetSeason(Anime::SeriesSeason::Summer, 2011U);
+			});
+		}
 
 		toolbar->addSeparator();
 
@@ -185,5 +191,5 @@
 	full_layout->setSpacing(0);
 
 	/* Do NOT move this up in this function, buttons HAS to be initialized */
-	SetSeason(Anime::SeriesSeason::Summer, 2011);
+	SetSeason(Anime::SeriesSeason::Summer, 2011U);
 }
--- a/src/gui/translate/anilist.cc	Mon May 13 15:19:55 2024 -0400
+++ b/src/gui/translate/anilist.cc	Mon May 13 17:02:35 2024 -0400
@@ -47,5 +47,15 @@
 	return map.at(format);
 }
 
+std::string ToString(Anime::SeriesSeason season) {
+	switch (season) {
+		default:
+		case Anime::SeriesSeason::Winter: return "WINTER";
+		case Anime::SeriesSeason::Fall: return "FALL";
+		case Anime::SeriesSeason::Summer: return "SUMMER";
+		case Anime::SeriesSeason::Spring: return "SPRING";
+	}
+}
+
 } // namespace AniList
 } // namespace Translate
--- a/src/services/anilist.cc	Mon May 13 15:19:55 2024 -0400
+++ b/src/services/anilist.cc	Mon May 13 17:02:35 2024 -0400
@@ -1,6 +1,7 @@
 #include "services/anilist.h"
 #include "core/anime.h"
 #include "core/anime_db.h"
+#include "core/date.h"
 #include "core/config.h"
 #include "core/http.h"
 #include "core/json.h"
@@ -28,6 +29,30 @@
 namespace AniList {
 
 static constexpr std::string_view CLIENT_ID = "13706";
+#define MEDIA_FIELDS \
+	"coverImage {\n" \
+	"  large\n" \
+	"}\n" \
+	"id\n" \
+	"title {\n" \
+	"  romaji\n" \
+	"  english\n" \
+	"  native\n" \
+	"}\n" \
+	"format\n" \
+	"status\n" \
+	"averageScore\n" \
+	"season\n" \
+	"startDate {\n" \
+	"  year\n" \
+	"  month\n" \
+	"  day\n" \
+	"}\n" \
+	"genres\n" \
+	"episodes\n" \
+	"duration\n" \
+	"synonyms\n" \
+	"description(asHtml: false)\n"
 
 class Account {
 public:
@@ -215,29 +240,7 @@
 	                                   "        }\n"
 	                                   "        updatedAt\n"
 	                                   "        media {\n"
-	                                   "          coverImage {\n"
-	                                   "            large\n"
-	                                   "          }\n"
-	                                   "          id\n"
-	                                   "          title {\n"
-	                                   "            romaji\n"
-	                                   "            english\n"
-	                                   "            native\n"
-	                                   "          }\n"
-	                                   "          format\n"
-	                                   "          status\n"
-	                                   "          averageScore\n"
-	                                   "          season\n"
-	                                   "          startDate {\n"
-	                                   "            year\n"
-	                                   "            month\n"
-	                                   "            day\n"
-	                                   "          }\n"
-	                                   "          genres\n"
-	                                   "          episodes\n"
-	                                   "          duration\n"
-	                                   "          synonyms\n"
-	                                   "          description(asHtml: false)\n"
+	                                   MEDIA_FIELDS
 	                                   "        }\n"
 	                                   "      }\n"
 	                                   "    }\n"
@@ -254,9 +257,9 @@
 
 	auto res = SendJSONRequest(json);
 
-	for (const auto& list : res["data"]["MediaListCollection"]["lists"].items()) {
+	for (const auto& list : res["data"]["MediaListCollection"]["lists"].items())
 		ParseList(list.value());
-	}
+
 	return 1;
 }
 
@@ -265,30 +268,7 @@
 	constexpr std::string_view query = "query ($search: String) {\n"
 	                                   "  Page (page: 1, perPage: 50) {\n"
 	                                   "    media (search: $search, type: ANIME) {\n"
-	                                   "      coverImage {\n"
-	                                   "        large\n"
-	                                   "      }\n"
-	                                   "      id\n"
-	                                   "      id_mal\n"
-	                                   "      title {\n"
-	                                   "        romaji\n"
-	                                   "        english\n"
-	                                   "        native\n"
-	                                   "      }\n"
-	                                   "      format\n"
-	                                   "      status\n"
-	                                   "      averageScore\n"
-	                                   "      season\n"
-	                                   "      startDate {\n"
-	                                   "        year\n"
-	                                   "        month\n"
-	                                   "        day\n"
-	                                   "      }\n"
-	                                   "      genres\n"
-	                                   "      episodes\n"
-	                                   "      duration\n"
-	                                   "      synonyms\n"
-	                                   "      description(asHtml: false)\n"
+	                                   MEDIA_FIELDS
 	                                   "    }\n"
 	                                   "  }\n"
 	                                   "}\n";
@@ -304,6 +284,7 @@
 
 	auto res = SendJSONRequest(json);
 
+	/* FIXME: error handling here */
 	std::vector<int> ret;
 	ret.reserve(res["data"]["Page"]["media"].size());
 
@@ -313,6 +294,49 @@
 	return ret;
 }
 
+std::vector<int> GetSeason(Anime::SeriesSeason season, Date::Year year) {
+	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";
+	std::vector<int> ret;
+
+	int page = 0;
+	bool has_next_page = true;
+	while (has_next_page) {
+		nlohmann::json json = {
+			{"query", query},
+			{"variables", {
+				{"season", Translate::AniList::ToString(season)},
+				{"season_year", Strings::ToUtf8String(year)},
+				{"page", page}
+			}}
+		};
+
+		auto res = SendJSONRequest(json);
+		ret.reserve(ret.capacity() + res["data"]["Page"]["media"].size());
+
+		for (const auto& media : res["data"]["Page"]["media"].items())
+			ret.push_back(ParseMediaJson(media.value()));
+
+		has_next_page = JSON::GetBoolean(res, "/data/Page/pageInfo/hasNextPage"_json_pointer, false);
+		if (has_next_page)
+			page++;
+	}
+
+	return ret;
+}
+
 int UpdateAnimeEntry(int id) {
 	/**
 	 * possible values:
--- a/src/services/services.cc	Mon May 13 15:19:55 2024 -0400
+++ b/src/services/services.cc	Mon May 13 17:02:35 2024 -0400
@@ -19,6 +19,13 @@
 	}
 }
 
+std::vector<int> GetSeason(Anime::SeriesSeason season, Date::Year year) {
+	switch (session.config.service) {
+		case Anime::Service::AniList: return AniList::GetSeason(season, year);
+		default: return {};
+	}
+}
+
 void UpdateAnimeEntry(int id) {
 	switch (session.config.service) {
 		case Anime::Service::AniList: AniList::UpdateAnimeEntry(id); break;