mirror of
https://github.com/FunKey-Project/RetroFE.git
synced 2026-03-19 18:32:53 +01:00
Port from git
This commit is contained in:
67
Source/Collection/CollectionInfo.cpp
Normal file
67
Source/Collection/CollectionInfo.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#include "CollectionInfo.h"
|
||||
#include "../Database/Configuration.h"
|
||||
#include <sstream>
|
||||
|
||||
CollectionInfo::CollectionInfo(std::string name,
|
||||
std::string listPath,
|
||||
std::string extensions,
|
||||
std::string metadataType,
|
||||
std::string metadataPath)
|
||||
: Name(name)
|
||||
, ListPath(listPath)
|
||||
, Extensions(extensions)
|
||||
, MetadataType(metadataType)
|
||||
, MetadataPath(metadataPath)
|
||||
{
|
||||
}
|
||||
|
||||
CollectionInfo::~CollectionInfo()
|
||||
{
|
||||
}
|
||||
|
||||
std::string CollectionInfo::GetName() const
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
std::string CollectionInfo::GetSettingsPath() const
|
||||
{
|
||||
return Configuration::GetAbsolutePath() + "/Collections/" + GetName();
|
||||
}
|
||||
|
||||
std::string CollectionInfo::GetListPath() const
|
||||
{
|
||||
return ListPath;
|
||||
}
|
||||
|
||||
std::string CollectionInfo::GetMetadataType() const
|
||||
{
|
||||
return MetadataType;
|
||||
}
|
||||
|
||||
std::string CollectionInfo::GetMetadataPath() const
|
||||
{
|
||||
return MetadataPath;
|
||||
}
|
||||
|
||||
std::string CollectionInfo::GetExtensions() const
|
||||
{
|
||||
return Extensions;
|
||||
}
|
||||
|
||||
void CollectionInfo::GetExtensions(std::vector<std::string> &extensions)
|
||||
{
|
||||
std::istringstream ss(Extensions);
|
||||
std::string token;
|
||||
|
||||
while(std::getline(ss, token, ','))
|
||||
{
|
||||
extensions.push_back(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
28
Source/Collection/CollectionInfo.h
Normal file
28
Source/Collection/CollectionInfo.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CollectionInfo
|
||||
{
|
||||
public:
|
||||
CollectionInfo(std::string name, std::string listPath, std::string extensions, std::string metadataType, std::string metadataPath);
|
||||
virtual ~CollectionInfo();
|
||||
std::string GetName() const;
|
||||
std::string GetSettingsPath() const;
|
||||
std::string GetListPath() const;
|
||||
std::string GetMetadataType() const;
|
||||
std::string GetMetadataPath() const;
|
||||
std::string GetExtensions() const;
|
||||
void GetExtensions(std::vector<std::string> &extensions);
|
||||
|
||||
private:
|
||||
std::string Name;
|
||||
std::string ListPath;
|
||||
std::string Extensions;
|
||||
std::string MetadataType;
|
||||
std::string MetadataPath;
|
||||
};
|
||||
126
Source/Collection/CollectionInfoBuilder.cpp
Normal file
126
Source/Collection/CollectionInfoBuilder.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "CollectionInfoBuilder.h"
|
||||
#include "CollectionInfo.h"
|
||||
#include "../Database/Configuration.h"
|
||||
#include "../Utility/Log.h"
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
CollectionInfoBuilder::CollectionInfoBuilder(Configuration *c)
|
||||
: Conf(c)
|
||||
{
|
||||
}
|
||||
|
||||
CollectionInfoBuilder::~CollectionInfoBuilder()
|
||||
{
|
||||
std::map<std::string, CollectionInfo *>::iterator it = InfoMap.begin();
|
||||
|
||||
for(it == InfoMap.begin(); it != InfoMap.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
InfoMap.clear();
|
||||
}
|
||||
|
||||
bool CollectionInfoBuilder::LoadAllCollections()
|
||||
{
|
||||
std::vector<std::string> collections;
|
||||
|
||||
Conf->GetChildKeyCrumbs("collections", collections);
|
||||
|
||||
if(collections.size() == 0)
|
||||
{
|
||||
Logger::Write(Logger::ZONE_ERROR, "Collections", "No collections were found. Please configure Settings.conf");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool retVal = true;
|
||||
std::vector<std::string>::iterator it;
|
||||
|
||||
for(it = collections.begin(); it != collections.end(); ++it)
|
||||
{
|
||||
// todo: There is nothing that should really stop us from creating a collection
|
||||
// in the main folder. I just need to find some time to look at the impacts if
|
||||
// I remove this conditional check.
|
||||
if(*it != "Main")
|
||||
{
|
||||
if(ImportCollection(*it))
|
||||
{
|
||||
Logger::Write(Logger::ZONE_INFO, "Collections", "Adding collection " + *it);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Continue processing the rest of the collections if an error occurs during import.
|
||||
// ImportCollection() will print out an error to the log file.
|
||||
retVal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void CollectionInfoBuilder::GetCollections(std::vector<CollectionInfo *> &collections)
|
||||
{
|
||||
std::map<std::string, CollectionInfo *>::iterator InfoMapIt;
|
||||
|
||||
for(InfoMapIt = InfoMap.begin(); InfoMapIt != InfoMap.end(); ++InfoMapIt)
|
||||
{
|
||||
collections.push_back(InfoMapIt->second);
|
||||
}
|
||||
}
|
||||
|
||||
bool CollectionInfoBuilder::ImportCollection(std::string name)
|
||||
{
|
||||
// create a new instance if one does not exist
|
||||
if(InfoMap.find(name) != InfoMap.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
std::string listItemsPathKey = "collections." + name + ".list.path";
|
||||
std::string listFilterKey = "collections." + name + ".list.filter";
|
||||
std::string extensionsKey = "collections." + name + ".list.extensions";
|
||||
std::string launcherKey = "collections." + name + ".launcher";
|
||||
|
||||
//todo: metadata is not fully not implemented
|
||||
std::string metadataTypeKey = "collections." + name + ".metadata.type";
|
||||
std::string metadataPathKey = "collections." + name + ".metadata.path";
|
||||
|
||||
std::string listItemsPath;
|
||||
std::string launcherName;
|
||||
std::string extensions;
|
||||
std::string metadataType;
|
||||
std::string metadataPath;
|
||||
|
||||
if(!Conf->GetPropertyAbsolutePath(listItemsPathKey, listItemsPath))
|
||||
{
|
||||
Logger::Write(Logger::ZONE_INFO, "Collections", "Property \"" + listItemsPathKey + "\" does not exist. Assuming \"" + name + "\" is a menu");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Conf->GetProperty(extensionsKey, extensions))
|
||||
{
|
||||
Logger::Write(Logger::ZONE_INFO, "Collections", "Property \"" + extensionsKey + "\" does not exist. Assuming \"" + name + "\" is a menu");
|
||||
return false;
|
||||
}
|
||||
|
||||
(void)Conf->GetProperty(metadataTypeKey, metadataType);
|
||||
(void)Conf->GetProperty(metadataPathKey, metadataPath);
|
||||
|
||||
if(!Conf->GetProperty(launcherKey, launcherName))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Warning: launcher property \""
|
||||
<< launcherKey
|
||||
<< "\" points to a launcher that is not configured (launchers."
|
||||
<< launcherName
|
||||
<< "). Your collection will be viewable, however you will not be able to "
|
||||
<< "launch any of the items in your collection.";
|
||||
|
||||
Logger::Write(Logger::ZONE_WARNING, "Collections", ss.str());
|
||||
}
|
||||
|
||||
InfoMap[name] = new CollectionInfo(name, listItemsPath, extensions, metadataType, metadataPath);
|
||||
|
||||
return (InfoMap[name] != NULL);
|
||||
}
|
||||
25
Source/Collection/CollectionInfoBuilder.h
Normal file
25
Source/Collection/CollectionInfoBuilder.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class Configuration;
|
||||
class CollectionInfo;
|
||||
|
||||
class CollectionInfoBuilder
|
||||
{
|
||||
public:
|
||||
CollectionInfoBuilder(Configuration *c);
|
||||
virtual ~CollectionInfoBuilder();
|
||||
bool LoadAllCollections();
|
||||
void GetCollections(std::vector<CollectionInfo *> &keys);
|
||||
|
||||
private:
|
||||
bool ImportCollection(std::string name);
|
||||
std::map<std::string, CollectionInfo *> InfoMap;
|
||||
Configuration *Conf;
|
||||
};
|
||||
160
Source/Collection/Item.cpp
Normal file
160
Source/Collection/Item.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#include "Item.h"
|
||||
#include "../Utility/Utils.h"
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
Item::Item()
|
||||
: NumberPlayers(0)
|
||||
, NumberButtons(0)
|
||||
, Leaf(true)
|
||||
{
|
||||
}
|
||||
|
||||
Item::~Item()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string Item::GetFileName() const
|
||||
{
|
||||
return Utils::GetFileName(FilePath);
|
||||
}
|
||||
|
||||
const std::string& Item::GetFilePath() const
|
||||
{
|
||||
return FilePath;
|
||||
}
|
||||
|
||||
void Item::SetFilePath(const std::string& filepath)
|
||||
{
|
||||
FilePath = filepath;
|
||||
}
|
||||
|
||||
const std::string& Item::GetLauncher() const
|
||||
{
|
||||
return Launcher;
|
||||
}
|
||||
|
||||
void Item::SetLauncher(const std::string& launcher)
|
||||
{
|
||||
Launcher = launcher;
|
||||
}
|
||||
|
||||
const std::string& Item::GetManufacturer() const
|
||||
{
|
||||
return Manufacturer;
|
||||
}
|
||||
|
||||
void Item::SetManufacturer(const std::string& manufacturer)
|
||||
{
|
||||
Manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
const std::string& Item::GetName() const
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
void Item::SetName(const std::string& name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
int Item::GetNumberButtons() const
|
||||
{
|
||||
return NumberButtons;
|
||||
}
|
||||
|
||||
std::string Item::GetNumberButtonsString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << NumberButtons;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
void Item::SetNumberButtons(int numberbuttons)
|
||||
{
|
||||
NumberButtons = numberbuttons;
|
||||
}
|
||||
|
||||
int Item::GetNumberPlayers() const
|
||||
{
|
||||
return NumberPlayers;
|
||||
}
|
||||
|
||||
std::string Item::GetNumberPlayersString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << NumberButtons;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
void Item::SetNumberPlayers(int numberplayers)
|
||||
{
|
||||
NumberPlayers = numberplayers;
|
||||
}
|
||||
|
||||
const std::string& Item::GetTitle() const
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
|
||||
const std::string& Item::GetLCTitle() const
|
||||
{
|
||||
return LCTitle;
|
||||
}
|
||||
|
||||
void Item::SetTitle(const std::string& title)
|
||||
{
|
||||
Title = title;
|
||||
LCTitle = Title;
|
||||
std::transform(LCTitle.begin(), LCTitle.end(), LCTitle.begin(), ::tolower);
|
||||
}
|
||||
|
||||
const std::string& Item::GetYear() const
|
||||
{
|
||||
return Year;
|
||||
}
|
||||
|
||||
void Item::SetYear(const std::string& year)
|
||||
{
|
||||
Year = year;
|
||||
}
|
||||
|
||||
bool Item::IsLeaf() const
|
||||
{
|
||||
return Leaf;
|
||||
}
|
||||
|
||||
void Item::SetIsLeaf(bool leaf)
|
||||
{
|
||||
Leaf = leaf;
|
||||
}
|
||||
|
||||
const std::string& Item::GetFullTitle() const
|
||||
{
|
||||
return FullTitle;
|
||||
}
|
||||
|
||||
void Item::SetFullTitle(const std::string& fulltitle)
|
||||
{
|
||||
FullTitle = fulltitle;
|
||||
}
|
||||
|
||||
const std::string& Item::GetCloneOf() const
|
||||
{
|
||||
return CloneOf;
|
||||
}
|
||||
|
||||
void Item::SetCloneOf(const std::string& cloneOf)
|
||||
{
|
||||
CloneOf = cloneOf;
|
||||
}
|
||||
|
||||
bool Item::operator<(const Item &rhs) { return LCTitle < rhs.LCTitle; }
|
||||
bool Item::operator>(const Item &rhs) { return LCTitle > rhs.LCTitle; }
|
||||
|
||||
56
Source/Collection/Item.h
Normal file
56
Source/Collection/Item.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Item
|
||||
{
|
||||
public:
|
||||
Item();
|
||||
virtual ~Item();
|
||||
const std::string GetFileName() const;
|
||||
const std::string& GetFilePath() const;
|
||||
void SetFilePath(const std::string& filepath);
|
||||
const std::string& GetLauncher() const;
|
||||
void SetLauncher(const std::string& launcher);
|
||||
const std::string& GetManufacturer() const;
|
||||
void SetManufacturer(const std::string& manufacturer);
|
||||
const std::string& GetName() const;
|
||||
void SetName(const std::string& name);
|
||||
int GetNumberButtons() const;
|
||||
std::string GetNumberButtonsString();
|
||||
void SetNumberButtons(int numberbuttons);
|
||||
void SetNumberPlayers(int numberplayers);
|
||||
int GetNumberPlayers() const;
|
||||
std::string GetNumberPlayersString();
|
||||
const std::string& GetTitle() const;
|
||||
const std::string& GetLCTitle() const;
|
||||
void SetTitle(const std::string& title);
|
||||
const std::string& GetYear() const;
|
||||
void SetYear(const std::string& year);
|
||||
bool IsLeaf() const;
|
||||
void SetIsLeaf(bool leaf);
|
||||
const std::string& GetFullTitle() const;
|
||||
void SetFullTitle(const std::string& fulltitle);
|
||||
const std::string& GetCloneOf() const;
|
||||
void SetCloneOf(const std::string& cloneOf);
|
||||
bool operator<(const Item& rhs);
|
||||
bool operator>(const Item& rhs);
|
||||
|
||||
private:
|
||||
std::string Launcher;
|
||||
std::string FilePath;
|
||||
std::string Name;
|
||||
std::string Title;
|
||||
std::string LCTitle;
|
||||
std::string FullTitle;
|
||||
std::string Year;
|
||||
std::string Manufacturer;
|
||||
std::string CloneOf;
|
||||
int NumberPlayers;
|
||||
int NumberButtons;
|
||||
bool Leaf;
|
||||
};
|
||||
|
||||
108
Source/Collection/MenuParser.cpp
Normal file
108
Source/Collection/MenuParser.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#include "MenuParser.h"
|
||||
#include "Item.h"
|
||||
#include "../Utility/Log.h"
|
||||
#include "../Database/Configuration.h"
|
||||
#include "../Database/CollectionDatabase.h"
|
||||
#include "../Database/DB.h"
|
||||
#include <algorithm>
|
||||
#include <rapidxml.hpp>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
bool VectorSort(const Item *d1, const Item *d2)
|
||||
{
|
||||
return d1->GetLCTitle() < d2->GetLCTitle();
|
||||
}
|
||||
|
||||
MenuParser::MenuParser()
|
||||
{
|
||||
}
|
||||
|
||||
MenuParser::~MenuParser()
|
||||
{
|
||||
}
|
||||
|
||||
//todo: clean up this method, too much nesting
|
||||
bool MenuParser::GetMenuItems(CollectionDatabase *cdb, std::string collectionName, std::vector<Item *> &items)
|
||||
{
|
||||
bool retVal = false;
|
||||
//todo: magic string
|
||||
std::string menuFilename = Configuration::GetAbsolutePath() + "/Collections/" + collectionName + "/Menu.xml";
|
||||
rapidxml::xml_document<> doc;
|
||||
rapidxml::xml_node<> * rootNode;
|
||||
|
||||
Logger::Write(Logger::ZONE_INFO, "Menu", "Checking if menu exists at \"" + menuFilename + "\"");
|
||||
|
||||
try
|
||||
{
|
||||
std::ifstream file(menuFilename.c_str());
|
||||
|
||||
// gracefully exit if there is no menu file for the pa
|
||||
if(file.good())
|
||||
{
|
||||
Logger::Write(Logger::ZONE_INFO, "Menu", "Found menu");
|
||||
std::vector<char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
buffer.push_back('\0');
|
||||
|
||||
doc.parse<0>(&buffer[0]);
|
||||
|
||||
rootNode = doc.first_node("menu");
|
||||
|
||||
for (rapidxml::xml_node<> * itemNode = rootNode->first_node("item"); itemNode; itemNode = itemNode->next_sibling())
|
||||
{
|
||||
rapidxml::xml_attribute<> *collectionAttribute = itemNode->first_attribute("collection");
|
||||
rapidxml::xml_attribute<> *importAttribute = itemNode->first_attribute("import");
|
||||
|
||||
if(!collectionAttribute)
|
||||
{
|
||||
retVal = false;
|
||||
Logger::Write(Logger::ZONE_ERROR, "Menu", "Menu item tag is missing collection attribute");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//todo: too much nesting! Ack!
|
||||
std::string import;
|
||||
if(importAttribute)
|
||||
{
|
||||
import = importAttribute->value();
|
||||
}
|
||||
if(import != "true")
|
||||
{
|
||||
//todo, check for empty string
|
||||
std::string title = collectionAttribute->value();
|
||||
Item *item = new Item();
|
||||
item->SetTitle(title);
|
||||
item->SetFullTitle(title);
|
||||
item->SetName(collectionAttribute->value());
|
||||
item->SetIsLeaf(false);
|
||||
items.push_back(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string collectionName = collectionAttribute->value();
|
||||
Logger::Write(Logger::ZONE_INFO, "Menu", "Loading collection into menu: " + collectionName);
|
||||
cdb->GetCollection(collectionAttribute->value(), items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( items.begin(), items.end(), VectorSort);
|
||||
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
catch(std::ifstream::failure &e)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Unable to open menu file \"" << menuFilename << "\": " << e.what();
|
||||
Logger::Write(Logger::ZONE_ERROR, "Menu", ss.str());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
}
|
||||
17
Source/Collection/MenuParser.h
Normal file
17
Source/Collection/MenuParser.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE.txt', which is part of this source code package.
|
||||
*/
|
||||
#pragma once
|
||||
#include "Item.h"
|
||||
#include <vector>
|
||||
|
||||
class CollectionDatabase;
|
||||
|
||||
class MenuParser
|
||||
{
|
||||
public:
|
||||
MenuParser();
|
||||
virtual ~MenuParser();
|
||||
bool GetMenuItems(CollectionDatabase *cdb, std::string collectionName, std::vector<Item *> &items);
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user