Mercurial > minori
comparison src/services/anilist.cc @ 304:2115488eb302
*: add very early season searcher
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Mon, 13 May 2024 17:02:35 -0400 |
parents | 9a88e1725fd2 |
children | 91ac90a34003 |
comparison
equal
deleted
inserted
replaced
303:ab7ff259b4ca | 304:2115488eb302 |
---|---|
1 #include "services/anilist.h" | 1 #include "services/anilist.h" |
2 #include "core/anime.h" | 2 #include "core/anime.h" |
3 #include "core/anime_db.h" | 3 #include "core/anime_db.h" |
4 #include "core/date.h" | |
4 #include "core/config.h" | 5 #include "core/config.h" |
5 #include "core/http.h" | 6 #include "core/http.h" |
6 #include "core/json.h" | 7 #include "core/json.h" |
7 #include "core/session.h" | 8 #include "core/session.h" |
8 #include "core/strings.h" | 9 #include "core/strings.h" |
26 | 27 |
27 namespace Services { | 28 namespace Services { |
28 namespace AniList { | 29 namespace AniList { |
29 | 30 |
30 static constexpr std::string_view CLIENT_ID = "13706"; | 31 static constexpr std::string_view CLIENT_ID = "13706"; |
32 #define MEDIA_FIELDS \ | |
33 "coverImage {\n" \ | |
34 " large\n" \ | |
35 "}\n" \ | |
36 "id\n" \ | |
37 "title {\n" \ | |
38 " romaji\n" \ | |
39 " english\n" \ | |
40 " native\n" \ | |
41 "}\n" \ | |
42 "format\n" \ | |
43 "status\n" \ | |
44 "averageScore\n" \ | |
45 "season\n" \ | |
46 "startDate {\n" \ | |
47 " year\n" \ | |
48 " month\n" \ | |
49 " day\n" \ | |
50 "}\n" \ | |
51 "genres\n" \ | |
52 "episodes\n" \ | |
53 "duration\n" \ | |
54 "synonyms\n" \ | |
55 "description(asHtml: false)\n" | |
31 | 56 |
32 class Account { | 57 class Account { |
33 public: | 58 public: |
34 int UserId() const { return session.config.auth.anilist.user_id; } | 59 int UserId() const { return session.config.auth.anilist.user_id; } |
35 void SetUserId(const int id) { session.config.auth.anilist.user_id = id; } | 60 void SetUserId(const int id) { session.config.auth.anilist.user_id = id; } |
213 " month\n" | 238 " month\n" |
214 " day\n" | 239 " day\n" |
215 " }\n" | 240 " }\n" |
216 " updatedAt\n" | 241 " updatedAt\n" |
217 " media {\n" | 242 " media {\n" |
218 " coverImage {\n" | 243 MEDIA_FIELDS |
219 " large\n" | |
220 " }\n" | |
221 " id\n" | |
222 " title {\n" | |
223 " romaji\n" | |
224 " english\n" | |
225 " native\n" | |
226 " }\n" | |
227 " format\n" | |
228 " status\n" | |
229 " averageScore\n" | |
230 " season\n" | |
231 " startDate {\n" | |
232 " year\n" | |
233 " month\n" | |
234 " day\n" | |
235 " }\n" | |
236 " genres\n" | |
237 " episodes\n" | |
238 " duration\n" | |
239 " synonyms\n" | |
240 " description(asHtml: false)\n" | |
241 " }\n" | 244 " }\n" |
242 " }\n" | 245 " }\n" |
243 " }\n" | 246 " }\n" |
244 " }\n" | 247 " }\n" |
245 "}\n"; | 248 "}\n"; |
252 }; | 255 }; |
253 // clang-format on | 256 // clang-format on |
254 | 257 |
255 auto res = SendJSONRequest(json); | 258 auto res = SendJSONRequest(json); |
256 | 259 |
257 for (const auto& list : res["data"]["MediaListCollection"]["lists"].items()) { | 260 for (const auto& list : res["data"]["MediaListCollection"]["lists"].items()) |
258 ParseList(list.value()); | 261 ParseList(list.value()); |
259 } | 262 |
260 return 1; | 263 return 1; |
261 } | 264 } |
262 | 265 |
263 /* return is a vector of anime ids */ | 266 /* return is a vector of anime ids */ |
264 std::vector<int> Search(const std::string& search) { | 267 std::vector<int> Search(const std::string& search) { |
265 constexpr std::string_view query = "query ($search: String) {\n" | 268 constexpr std::string_view query = "query ($search: String) {\n" |
266 " Page (page: 1, perPage: 50) {\n" | 269 " Page (page: 1, perPage: 50) {\n" |
267 " media (search: $search, type: ANIME) {\n" | 270 " media (search: $search, type: ANIME) {\n" |
268 " coverImage {\n" | 271 MEDIA_FIELDS |
269 " large\n" | |
270 " }\n" | |
271 " id\n" | |
272 " id_mal\n" | |
273 " title {\n" | |
274 " romaji\n" | |
275 " english\n" | |
276 " native\n" | |
277 " }\n" | |
278 " format\n" | |
279 " status\n" | |
280 " averageScore\n" | |
281 " season\n" | |
282 " startDate {\n" | |
283 " year\n" | |
284 " month\n" | |
285 " day\n" | |
286 " }\n" | |
287 " genres\n" | |
288 " episodes\n" | |
289 " duration\n" | |
290 " synonyms\n" | |
291 " description(asHtml: false)\n" | |
292 " }\n" | 272 " }\n" |
293 " }\n" | 273 " }\n" |
294 "}\n"; | 274 "}\n"; |
295 | 275 |
296 // clang-format off | 276 // clang-format off |
302 }; | 282 }; |
303 // clang-format on | 283 // clang-format on |
304 | 284 |
305 auto res = SendJSONRequest(json); | 285 auto res = SendJSONRequest(json); |
306 | 286 |
287 /* FIXME: error handling here */ | |
307 std::vector<int> ret; | 288 std::vector<int> ret; |
308 ret.reserve(res["data"]["Page"]["media"].size()); | 289 ret.reserve(res["data"]["Page"]["media"].size()); |
309 | 290 |
310 for (const auto& media : res["data"]["Page"]["media"].items()) | 291 for (const auto& media : res["data"]["Page"]["media"].items()) |
311 ret.push_back(ParseMediaJson(media.value())); | 292 ret.push_back(ParseMediaJson(media.value())); |
293 | |
294 return ret; | |
295 } | |
296 | |
297 std::vector<int> GetSeason(Anime::SeriesSeason season, Date::Year year) { | |
298 constexpr std::string_view query = "query ($season: MediaSeason!, $season_year: Int!, $page: Int) {\n" | |
299 " Page(page: $page) {\n" | |
300 " media(season: $season, seasonYear: $season_year, type: ANIME, sort: START_DATE) {\n" | |
301 MEDIA_FIELDS | |
302 " }\n" | |
303 " pageInfo {\n" | |
304 " total\n" | |
305 " perPage\n" | |
306 " currentPage\n" | |
307 " lastPage\n" | |
308 " hasNextPage\n" | |
309 " }\n" | |
310 " }\n" | |
311 "}\n"; | |
312 std::vector<int> ret; | |
313 | |
314 int page = 0; | |
315 bool has_next_page = true; | |
316 while (has_next_page) { | |
317 nlohmann::json json = { | |
318 {"query", query}, | |
319 {"variables", { | |
320 {"season", Translate::AniList::ToString(season)}, | |
321 {"season_year", Strings::ToUtf8String(year)}, | |
322 {"page", page} | |
323 }} | |
324 }; | |
325 | |
326 auto res = SendJSONRequest(json); | |
327 ret.reserve(ret.capacity() + res["data"]["Page"]["media"].size()); | |
328 | |
329 for (const auto& media : res["data"]["Page"]["media"].items()) | |
330 ret.push_back(ParseMediaJson(media.value())); | |
331 | |
332 has_next_page = JSON::GetBoolean(res, "/data/Page/pageInfo/hasNextPage"_json_pointer, false); | |
333 if (has_next_page) | |
334 page++; | |
335 } | |
312 | 336 |
313 return ret; | 337 return ret; |
314 } | 338 } |
315 | 339 |
316 int UpdateAnimeEntry(int id) { | 340 int UpdateAnimeEntry(int id) { |