view src/library/library.cc @ 367:8d45d892be88 default tip

*: instead of pugixml, use Qt XML features this means we have one extra Qt dependency though...
author Paper <paper@tflc.us>
date Sun, 17 Nov 2024 22:55:47 -0500
parents 886f66775f31
children
line wrap: on
line source

#include "library/library.h"
#include "core/anime_db.h"
#include "core/session.h"
#include "core/strings.h"

#include "anitomy/anitomy.h"

#include <filesystem>
#include <string>
#include <unordered_map>

#include <iostream>

namespace Library {

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
	// as well that fit the anime name and *also* have episodes in them.
	// it should give each of these directories a rating by how many
	// 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) {
		if (id != anime_id)
			continue;

		for (const auto& [episode, path] : episodes) {
			return path.parent_path();
			break;
		}

		break;
	}

	return std::nullopt;
}

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)) {
			const std::filesystem::path path = entry.path();
			if (!std::filesystem::is_regular_file(path))
				continue;

			const std::string basename = path.filename().u8string();

			anitomy::Anitomy anitomy;
			anitomy.Parse(basename);

			const auto& elements = anitomy.elements();

			const std::string title = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle));

			const int id = Anime::db.LookupAnimeTitle(title);
			if (id <= 0 || (find_id && find_id.value() != id))
				continue;

			const int episode = Strings::ToInt<int>(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber)));

			// we have an ID now!
			items[id][episode] = path;
		}
	}
}

void Database::Refresh() {
	Refresh(std::nullopt);
}

void Database::Refresh(int id) {
	Refresh(std::optional<int>(id));
}

// TODO export to JSON

Database db;

} // namespace Library