diff src/core/anime_db.cc @ 83:d02fdf1d6708

*: huuuge update 1. make the now playing page function correctly 2. de-constructorfy many of our custom widgets, allowing them to be changed on-the-fly from the Now Playing page 3. ... :)
author Paper <mrpapersonic@gmail.com>
date Tue, 24 Oct 2023 22:01:02 -0400
parents 9b2b41f83a5e
children de0a8d2f28b3
line wrap: on
line diff
--- a/src/core/anime_db.cc	Mon Oct 23 13:37:42 2023 -0400
+++ b/src/core/anime_db.cc	Tue Oct 24 22:01:02 2023 -0400
@@ -62,8 +62,9 @@
 	return total;
 }
 
-/* I'm sure many will appreciate this being called an
-   "average" instead of a "mean" */
+/* In Taiga this is called a mean, but "average" is
+   what's primarily used in conversation, at least
+   in the U.S. */
 double Database::GetAverageScore() {
 	double avg = 0;
 	int amt = 0;
@@ -88,19 +89,55 @@
 	return (amt > 0) ? std::sqrt(squares_sum / amt) : 0;
 }
 
-int Database::GetAnimeFromTitle(std::string title) {
+template <typename T, typename U>
+static T get_lowest_in_map(const std::unordered_map<T, U>& map) {
+	if (map.size() <= 0)
+		return 0;
+	T id;
+	U ret = std::numeric_limits<U>::max();
+	for (const auto& t : map) {
+		if (t.second < ret) {
+			ret = t.second;
+			id = t.first;
+		}
+	}
+	return id;
+}
+
+/* This is really fugly but WHO CARES :P
+
+   This sort of ""advanced"" algorithm is only in effect because
+   there are some special cases, e.g. Another and Re:ZERO, where 
+   we get the wrong match, so we have to create Advanced Techniques
+   to solve this
+
+   This algorithm:
+     1. searches each anime item for a match to the preferred title
+        AND all synonyms and marks those matches with
+          `synonym.length() - (synonym.find(needle) + needle.length());`
+        which, on a title that exactly matches, will be 0
+     2. returns the id of the match that is the lowest, which will most
+        definitely match anything that exactly matches the title of the
+        filename */
+int Database::GetAnimeFromTitle(const std::string& title) {
 	if (title.empty())
 		return 0;
+	std::unordered_map<int, long long> map;
 	for (const auto& a : items) {
-		if (a.second.GetUserPreferredTitle().find(title) != std::string::npos)
-			return a.second.GetId();
-		for (const auto& t : a.second.GetTitleSynonyms()) {
-			if (t.find(title) != std::string::npos) {
-				return a.second.GetId();
+		long long ret = a.second.GetUserPreferredTitle().find(title);
+		if (ret != static_cast<long long>(std::string::npos)) {
+			map[a.second.GetId()] = a.second.GetUserPreferredTitle().length() - (ret + title.length());
+			continue;
+		}
+		for (const auto& synonym : a.second.GetTitleSynonyms()) {
+			ret = synonym.find(title);
+			if (ret != static_cast<long long>(std::string::npos)) {
+				map[a.second.GetId()] = synonym.length() - (ret + title.length());
+				continue;
 			}
 		}
 	}
-	return 0;
+	return get_lowest_in_map(map);
 }
 
 Database db;