changeset 135:0a458cb26ff4

filesystem: move to using std::filesystem after C++17 switch old compilers will croak compiling this, but it's not like we *really* need to support them (they probably croak compiling Qt as well)
author Paper <mrpapersonic@gmail.com>
date Thu, 09 Nov 2023 18:01:56 -0500
parents 54c9d36207db
children 7d3ad9529c4c
files include/core/filesystem.h include/track/media.h src/core/config.cc src/core/filesystem.cc src/gui/window.cc src/track/media.cc src/track/types.cc
diffstat 7 files changed, 69 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/include/core/filesystem.h	Thu Nov 09 13:53:04 2023 -0500
+++ b/include/core/filesystem.h	Thu Nov 09 18:01:56 2023 -0500
@@ -1,32 +1,16 @@
 #ifndef __core__filesystem_h
 #define __core__filesystem_h
 #include <string>
+#include <filesystem>
 
 namespace Filesystem {
 
-class Path {
-	public:
-		Path();
-		Path(const std::string& path);
-		Path(const Path& path);
-		bool CreateDirectories() const;
-		bool Exists() const;
-		std::string Basename() const;
-		std::string Stem() const;
-		std::string Extension() const;
-		Path GetParent() const;
-		void SetPath(const std::string& path);
-		std::string GetPath() const;
-
-	private:
-		std::string _path;
-};
-
-Path GetDotPath();        // %APPDATA%/minori, ~/Library/Application Support/minori, ~/.config/minori...
-Path GetConfigPath();     // (dotpath)/config.json
-Path GetAnimeDBPath();    // (dotpath)/anime/db.json
-Path GetPlayersPath();    // (dotpath)/player.json
-Path GetExtensionsPath(); // (dotpath)/extensions.json
+void CreateDirectories(const std::filesystem::path& path);
+std::filesystem::path GetDotPath();        // %APPDATA%/minori, ~/Library/Application Support/minori, ~/.config/minori...
+std::filesystem::path GetConfigPath();     // (dotpath)/config.json
+std::filesystem::path GetAnimeDBPath();    // (dotpath)/anime/db.json
+std::filesystem::path GetPlayersPath();    // (dotpath)/player.json
+std::filesystem::path GetExtensionsPath(); // (dotpath)/extensions.json
 
 } // namespace Filesystem
 
--- a/include/track/media.h	Thu Nov 09 13:53:04 2023 -0500
+++ b/include/track/media.h	Thu Nov 09 18:01:56 2023 -0500
@@ -6,9 +6,9 @@
 namespace Track {
 namespace Media {
 
-Filesystem::Path GetCurrentPlaying();
-std::unordered_map<std::string, std::string> GetFileElements(std::string basename);
-std::unordered_map<std::string, std::string> GetFileElements(Filesystem::Path path);
+std::filesystem::path GetCurrentPlaying();
+std::unordered_map<std::string, std::string> GetFileElements(const std::string& basename);
+std::unordered_map<std::string, std::string> GetFileElements(const std::filesystem::path& path);
 
 } // namespace Media
 } // namespace Track
--- a/src/core/config.cc	Thu Nov 09 13:53:04 2023 -0500
+++ b/src/core/config.cc	Thu Nov 09 18:01:56 2023 -0500
@@ -21,9 +21,9 @@
    XML file like Taiga. */
 
 int Config::Load() {
-	Filesystem::Path cfg_path = Filesystem::GetConfigPath();
+	std::filesystem::path cfg_path = Filesystem::GetConfigPath();
 
-	mINI::INIFile file(cfg_path.GetPath());
+	mINI::INIFile file(cfg_path.string());
 	mINI::INIStructure ini;
 	file.read(ini);
 
@@ -40,6 +40,8 @@
 
 	torrents.feed_link = INI::GetIniValue<std::string>(ini, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0");
 
+	recognition.detect_media_players = INI::GetIniValue<bool>(ini, "Recognition", "Detect media players", true);
+
 	/* ew */
 	locale.SetActiveLocale(QLocale(Strings::ToQString(INI::GetIniValue<std::string>(ini, "General", "Locale", "en_US"))));
 
@@ -49,11 +51,10 @@
 }
 
 int Config::Save() const {
-	Filesystem::Path cfg_path = Filesystem::GetConfigPath();
-	if (!cfg_path.GetParent().Exists())
-		cfg_path.GetParent().CreateDirectories();
+	std::filesystem::path cfg_path = Filesystem::GetConfigPath();
+	Filesystem::CreateDirectories(cfg_path);
 
-	mINI::INIFile file(cfg_path.GetPath());
+	mINI::INIFile file(cfg_path.string());
 	mINI::INIStructure ini;
 
 	INI::SetIniValue(ini, "General", "Service", service);
@@ -73,7 +74,6 @@
 	INI::SetIniValue(ini, "Torrents", "RSS feed", torrents.feed_link);
 
 	INI::SetIniValue(ini, "Recognition", "Detect media players", recognition.detect_media_players);
-	//ini["Recognition"]["Detect streaming media"] = Strings::ToUtf8String(recognition.detect_streaming_media);
 
 	file.write(ini);
 
--- a/src/core/filesystem.cc	Thu Nov 09 13:53:04 2023 -0500
+++ b/src/core/filesystem.cc	Thu Nov 09 18:01:56 2023 -0500
@@ -19,139 +19,59 @@
 #include "core/filesystem.h"
 #include "core/config.h"
 #include "core/strings.h"
+#include <filesystem>
 #include <limits.h>
 
-/* TODO: remove this and use std::filesystem */
-
 namespace Filesystem {
 
-Path::Path() {
-	_path = "";
-}
-Path::Path(const std::string& path) {
-	_path = path;
-}
-Path::Path(const Path& path) {
-	_path = path.GetPath();
-}
-
-bool Path::CreateDirectories() const {
-	std::string temp = "";
-	size_t start;
-	size_t end = 0;
-	temp.append(_path.substr(0, _path.find_first_not_of(DELIM, end)));
-
-	while ((start = _path.find_first_not_of(DELIM, end)) != std::string::npos) {
-		end = _path.find(DELIM, start);
-		temp.append(_path.substr(start, end - start));
-#ifdef WIN32
-		if (!CreateDirectoryW(Strings::ToWstring(temp).c_str(), NULL) && GetLastError() == ERROR_PATH_NOT_FOUND)
-			/* ERROR_PATH_NOT_FOUND should NOT happen here */
-			return false;
-#else
-		struct stat st;
-		if (stat(temp.c_str(), &st) == -1)
-			mkdir(temp.c_str(), 0755);
-#endif
-		temp.append(DELIM);
-	}
-	return true;
-}
-
-bool Path::Exists() const {
-#ifdef WIN32
-	std::wstring buf = Strings::ToWstring(_path);
-	return GetFileAttributesW(buf.c_str()) != INVALID_FILE_ATTRIBUTES;
-#else
-	struct stat st;
-	return stat(_path.c_str(), &st) == 0;
-#endif
-}
-
-std::string Path::Basename() const {
-	unsigned long long pos = _path.find_last_of(DELIM);
-	return pos != std::string::npos ? _path.substr(pos + 1, _path.length()) : "";
-}
-
-std::string Path::Stem() const {
-	std::string basename = Basename();
-	unsigned long long pos = basename.find_last_of(".");
-	return pos != std::string::npos ? basename.substr(0, pos) : "";
-}
-
-std::string Path::Extension() const {
-	std::string basename = Basename();
-	unsigned long long pos = basename.find_last_of(".");
-	return pos != std::string::npos ? basename.substr(pos + 1, basename.length()) : "";
-}
-
-Path Path::GetParent() const {
-	return _path.substr(0, _path.find_last_of(DELIM));
+/* this runs fs::create_directories() on the
+   PARENT directory. */
+void CreateDirectories(const std::filesystem::path& path) {
+	std::filesystem::create_directories(path.parent_path());
 }
 
-void Path::SetPath(const std::string& path) {
-	_path = path;
-}
-
-std::string Path::GetPath() const {
-	return _path;
-}
-
-Path GetDotPath(void) {
-	std::string ret = "";
+std::filesystem::path GetDotPath() {
 #ifdef WIN32
-	std::wstring buf(MAX_PATH, '\0');
-	if (SHGetFolderPathAndSubDirW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, CONFIG_WDIR, &buf.front()) ==
-	    S_OK) {
-		buf.resize(buf.find('\0'));
-		ret += Strings::ToUtf8String(buf);
-	}
+	std::filesystem::path path;
+	wchar_t* buf;
+	if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE, NULL, &buf) == S_OK)
+		path = buf;
+	else
+		return std::filesystem::path();
+	CoTaskMemFree(buf);
+	return path / CONFIG_DIR;
 #elif defined(MACOSX)
-	ret += osx::GetApplicationSupportDirectory();
-	ret += DELIM CONFIG_DIR;
+	return std::filesystem::path(osx::GetApplicationSupportDirectory()) / CONFIG_DIR;
 #else // just assume POSIX
-	if (getenv("HOME") != NULL)
-		ret += getenv("HOME");
+	const char* home = getenv("HOME");
+	if (home != NULL)
+		path = home;
 #	ifdef __linux__
 	else
-		ret += getpwuid(getuid())->pw_dir;
+		path = getpwuid(getuid())->pw_dir;
 #	endif // __linux__
-	if (!ret.empty())
-		ret += DELIM ".config" DELIM CONFIG_DIR;
+	if (!path.empty())
+		return path / ".config";
+	else
+		return std::filesystem::path();
 #endif     // !WIN32 && !MACOSX
-	return ret;
-}
-
-Path GetConfigPath(void) {
-	std::string ret = "";
-	ret += GetDotPath().GetPath();
-	if (!ret.empty())
-		ret += DELIM CONFIG_NAME;
-	return ret;
+	return path / CONFIG_DIR;
 }
 
-Path GetPlayersPath(void) {
-	std::string ret = "";
-	ret += GetDotPath().GetPath();
-	if (!ret.empty())
-		ret += DELIM "players.json";
-	return ret;
+std::filesystem::path GetConfigPath() {
+	return GetDotPath() / CONFIG_NAME;
 }
 
-Path GetExtensionsPath(void) {
-	std::string ret = "";
-	ret += GetDotPath().GetPath();
-	if (!ret.empty())
-		ret += DELIM "extensions.json";
-	return ret;
+std::filesystem::path GetPlayersPath() {
+	return GetDotPath() / "recognition" / "players.json";
 }
 
-Path GetAnimeDBPath(void) {
-	std::string ret = "";
-	ret += GetDotPath().GetPath();
-	if (!ret.empty())
-		ret += DELIM "anime" DELIM "db.json";
-	return ret;
+std::filesystem::path GetExtensionsPath() {
+	return GetDotPath() / "recognition" / "extensions.json";
+}
+
+std::filesystem::path GetAnimeDBPath() {
+	return GetDotPath() / "anime" / "db.json";
 }
 
 } // namespace Filesystem
--- a/src/gui/window.cc	Thu Nov 09 13:53:04 2023 -0500
+++ b/src/gui/window.cc	Thu Nov 09 18:01:56 2023 -0500
@@ -64,11 +64,13 @@
 	CreateBars();
 
 	QTimer* timer = new QTimer(this);
+
+	/* this is very very stinky */
 	connect(timer, &QTimer::timeout, this, [this] {
 		NowPlayingPage* page = reinterpret_cast<NowPlayingPage*>(stack->widget(static_cast<int>(Pages::NOW_PLAYING)));
 
-		Filesystem::Path p = Track::Media::GetCurrentPlaying();
-		std::unordered_map<std::string, std::string> elements = Track::Media::GetFileElements(p);
+		std::filesystem::path path = Track::Media::GetCurrentPlaying();
+		std::unordered_map<std::string, std::string> elements = Track::Media::GetFileElements(path);
 		int id = Anime::db.GetAnimeFromTitle(elements["title"]);
 		if (id <= 0) {
 			page->SetDefault();
--- a/src/track/media.cc	Thu Nov 09 13:53:04 2023 -0500
+++ b/src/track/media.cc	Thu Nov 09 18:01:56 2023 -0500
@@ -13,9 +13,9 @@
 namespace Track {
 namespace Media {
 
-std::vector<Filesystem::Path> GetCurrentlyPlayingFiles() {
+std::vector<std::filesystem::path> GetCurrentlyPlayingFiles() {
 	/* getting all open files */
-	std::vector<Filesystem::Path> ret;
+	std::vector<std::filesystem::path> ret;
 
 	std::vector<int> pids = Animia::get_all_pids();
 	for (int pid : pids) {
@@ -24,10 +24,10 @@
 				continue;
 
 			for (const std::string& file : Animia::filter_system_files(Animia::get_open_files(pid))) {
-				const Filesystem::Path path(file);
+				const std::filesystem::path path(file);
 
 				for (const Types::MediaExtension& ext : session.recognition.extensions)
-					if (path.Extension() == ext.GetExtension())
+					if (path.extension() == ext.GetExtension())
 						ret.push_back(path);
 			}
 		}
@@ -36,12 +36,12 @@
 	return ret;
 }
 
-Filesystem::Path GetCurrentPlaying() {
+std::filesystem::path GetCurrentPlaying() {
 	/* getting all open files */
-	std::vector<Filesystem::Path> paths = GetCurrentlyPlayingFiles();
+	std::vector<std::filesystem::path> paths = GetCurrentlyPlayingFiles();
 	if (paths.size())
 		return paths.at(0);
-	return Filesystem::Path();
+	return std::filesystem::path();
 }
 
 std::unordered_map<std::string, std::string> GetMapFromElements(const anitomy::Elements& elements) {
@@ -59,16 +59,16 @@
 	return ret;
 }
 
-std::unordered_map<std::string, std::string> GetFileElements(std::string basename) {
+std::unordered_map<std::string, std::string> GetFileElements(const std::string& basename) {
 	anitomy::Anitomy anitomy;
 	anitomy.Parse(Strings::ToWstring(basename));
 
 	return GetMapFromElements(anitomy.elements());
 }
 
-std::unordered_map<std::string, std::string> GetFileElements(Filesystem::Path path) {
+std::unordered_map<std::string, std::string> GetFileElements(const std::filesystem::path& path) {
 	anitomy::Anitomy anitomy;
-	anitomy.Parse(Strings::ToWstring(path.Basename()));
+	anitomy.Parse(path.filename().wstring());
 
 	return GetMapFromElements(anitomy.elements());
 }
--- a/src/track/types.cc	Thu Nov 09 13:53:04 2023 -0500
+++ b/src/track/types.cc	Thu Nov 09 18:01:56 2023 -0500
@@ -195,7 +195,7 @@
 void LoadPlayers(std::vector<MediaPlayer>& players) {
 	nlohmann::json json;
 	{	
-		std::ifstream is(Filesystem::GetPlayersPath().GetPath());
+		std::ifstream is(Filesystem::GetPlayersPath().string());
 		if (!is.is_open())
 			json = default_players;
 		else
@@ -215,7 +215,7 @@
 void LoadExtensions(std::vector<MediaExtension>& extensions) {
 	nlohmann::json json;
 	{	
-		std::ifstream is(Filesystem::GetExtensionsPath().GetPath());
+		std::ifstream is(Filesystem::GetExtensionsPath().string());
 		if (!is.is_open())
 			json = default_extensions;
 		else
@@ -242,7 +242,7 @@
 	}
 
 	{
-		std::ofstream os(Filesystem::GetPlayersPath().GetPath());
+		std::ofstream os(Filesystem::GetPlayersPath().string());
 		if (!os.is_open())
 			return;
 		os << std::setw(4) << json << std::endl;
@@ -259,7 +259,7 @@
 	}
 
 	{
-		std::ofstream os(Filesystem::GetExtensionsPath().GetPath());
+		std::ofstream os(Filesystem::GetExtensionsPath().string());
 		if (!os.is_open())
 			return;
 		os << std::setw(4) << json << std::endl;