diff --git a/#SyncAction.h# b/#SyncAction.h# new file mode 100644 index 0000000..729e5da --- /dev/null +++ b/#SyncAction.h# @@ -0,0 +1,33 @@ +#ifndef _SYNCACTION_H +#define _SYNCACTION_H +#include "ConfigFile.h" +#include "3mExceptions.h" +#include "ModListList.h" +#include "ModListDescription.h" +#include "ModInfoDescription.h" +#include "ModDescription.h" +#include "LocalModDescription.h" +#include "ModList.h" +#include "ModInfo.h" +#include "NetSocket++/NetSocketPP.h" +#include "Action.h" +#include +/// \file SyncAction.h +/// \brief A Sync 3m action class. +/// \author Phitherek_ +/// \date 2013 +/// \version 0.1 + +/// \namespace mmm +/// \brief A global namespace for 3m. +namespace mmm { +/// \class SyncAction +/// \brief A Sync 3m action class. +class SyncAction: public Action { +public: + SyncAction(); ///< A constructor. + ~SyncAction(); ///< A destructor. + void run(); ///< A virtual function that executes the action. +}; +} +#endif diff --git a/3mExceptions.cpp b/3mExceptions.cpp index 1330a92..2a028b8 100644 --- a/3mExceptions.cpp +++ b/3mExceptions.cpp @@ -66,3 +66,27 @@ NonEditableException::~NonEditableException() throw() { const char* NonEditableException::what() const throw() { return _what.c_str(); } + +BadParameterException::BadParameterException(std::string parameter) { + _action = "global"; + _parameter = parameter; +} + +BadParameterException::BadParameterException(std::string action, std::string parameter) { + _action = action; + _parameter = parameter; +} + +BadParameterException::~BadParameterException() throw() { + _action = ""; + _parameter = ""; +} + +const char* BadParameterException::what() const throw() { + std::string swhat = ""; + swhat += "("; + swhat += _action; + swhat += ") Invalid parameter: "; + swhat += _parameter; + return swhat.c_str(); +} diff --git a/3mExceptions.h b/3mExceptions.h index 55e99e3..0486d76 100644 --- a/3mExceptions.h +++ b/3mExceptions.h @@ -65,5 +65,21 @@ public: const char* what() const throw(); ///< \brief A function returning error message. /// \return Error message. }; +/// \class BadParameterException +/// \brief An exception to be thrown on bad command line parameter. +class BadParameterException: public std::exception { +private: + std::string _action; + std::string _parameter; +public: + BadParameterException(std::string parameter); ///< \brief A constructor with parameter. + ///< \param parameter A parameter that caused the exception but is not any action parameter. + BadParameterException(std::string action, std::string parameter); ///< \brief A constructor with parameters. + ///< \param action An action where exception occured. + ///< \param parameter A parameter that caused the exception. + ~BadParameterException() throw(); ///< A destructor, as needed by std::exception. + const char* what() const throw(); ///< \brief A function returning error message. + /// \return Error message. +}; } #endif diff --git a/LocalModDescription.cpp b/LocalModDescription.cpp index 886e05a..8f4ca80 100644 --- a/LocalModDescription.cpp +++ b/LocalModDescription.cpp @@ -5,6 +5,24 @@ LocalModDescription::LocalModDescription() { _remoteModlist = ""; } +LocalModDescription::LocalModDescription(ModDescription cpy) { + _name = cpy.getName(); + _description = cpy.getDescription(); + _release = cpy.getReleaseNr(); + cpy.resetDependencyIterator(); + while(!cpy.dependenciesEnd()) { + std::string dep = cpy.getNextDependency(); + if(dep != "") { + _deps.push_back(dep); + } + } + _depsIterator = -1; + _depsAtEnd = false; + _repotype = cpy.getRepositoryType(); + _repoaddr = cpy.getRepositoryAddress(); + _remoteModlist = ""; +} + LocalModDescription::~LocalModDescription() { _remoteModlist = ""; } diff --git a/LocalModDescription.h b/LocalModDescription.h index 4e99bcc..1168272 100644 --- a/LocalModDescription.h +++ b/LocalModDescription.h @@ -18,6 +18,8 @@ std::string _remoteModlist; public: LocalModDescription(); ///< A constructor. ~LocalModDescription(); ///< A destructor. +LocalModDescription(ModDescription cpy); ///< \brief A converting constructor for ModDescription. +///< \param cpy ModDescription object to copy. std::string getRemoteModlistName(); ///< \brief A function returning remote modlist name. ///< \return Remote modlist name. void setRemoteModlistName(std::string remoteModlist); ///< \brief A function setting remote modlist name. diff --git a/SyncAction.cpp b/SyncAction.cpp new file mode 100644 index 0000000..c1340f2 --- /dev/null +++ b/SyncAction.cpp @@ -0,0 +1,92 @@ +#include "SyncAction.h" +#include +#include +using namespace mmm; + +SyncAction::SyncAction(): Action() {} + +SyncAction::~SyncAction() {} + +void SyncAction::run() { + try { + std::cout << "Starting Sync" << std::endl; + std::string home; + home = getenv("HOME"); + std::string confpath = home + "/.3m/config"; + mmm::ConfigFile config(confpath); + std::cout << "Config read successfully!" << std::endl; + mmm::ModListList rmodlists; + std::cout << "Remote modlist list read successfully!" << std::endl; + mmm::LocalModList lmodlist; + lmodlist.setConfigFile(config); + if(!parameters.empty()) { + for(unsigned int i = 0; i < parameters.size(); i++) { + try { + mmm::ModListDescription modlistdesc = rmodlists.getModlistDescriptionByName(parameters[i]); + if(modlistdesc.getName() == "" || modlistdesc.getServer() == "" || modlistdesc.getPath() == "") { + throw BadParameterException("sync", parameters[i]); + } + mmm::ModList modlist(modlistdesc); + while(!modlist.modinfosEnd()) { + mmm::ModDescription mod = modlist.getNextModInfo(); + if(mod.getName() != "" && mod.getDescription() != "" && mod.getReleaseNr() != 0 && mod.getRepositoryType() != "" && mod.getRepositoryAddress() != "") { + mmm::LocalModDescription localmod = mod; + localmod.setRemoteModlistName(modlistdesc.getName()); + lmodlist.addModDescription(localmod); + } else { + std::cout << "Empty mod description or end of list, skipping..." << std::endl; + } + } + } catch(BadParameterException &exc) { + std::cerr << "BadParameterException occured: " << exc.what() << "! Skipping..." << std::endl; + } catch(NetSocketPP::NetworkException &exc) { + std::cerr << "NetworkException occured in NetSocket++: " << exc.what() << "! Skipping..." << std::endl; + } catch(NetSocketPP::SocketException &exc) { + std::cerr << "SocketException occured in NetSocket++: " << exc.what() << "! Skipping..." << std::endl; + } catch(ParseException &exc) { + std::cerr << "ParseException occured: " << exc.what() << "! Skipping..." << std::endl; + } catch(BadResponseException &exc) { + std::cerr << "BadResponseException occured: " << exc.what() << "! Skipping..." << std::endl; + } + } + } else { + while(!rmodlists.modlistDescriptionsAtEnd()) { + try { + mmm::ModListDescription modlistdesc = rmodlists.getNextModlistDescription(); + mmm::ModListDescription emptymld; + if(modlistdesc.getName() != "" && modlistdesc.getServer() != "" && modlistdesc.getPath() != "") { + mmm::ModList modlist(modlistdesc); + while(!modlist.modinfosEnd()) { + mmm::ModDescription mod = modlist.getNextModInfo(); + if(mod.getName() != "" && mod.getDescription() != "" && mod.getReleaseNr() != 0 && mod.getRepositoryType() != "" && mod.getRepositoryAddress() != "") { + mmm::LocalModDescription localmod = mod; + localmod.setRemoteModlistName(modlistdesc.getName()); + lmodlist.addModDescription(localmod); + } else { + std::cout << "Empty mod description or end of list, skipping..." << std::endl; + } + } + } else { + std::cout << "Empty modlist description or end of list, skipping..." << std::endl; + } + } catch(NetSocketPP::NetworkException &exc) { + std::cerr << "NetworkException occured in NetSocket++: " << exc.what() << "! Skipping..." << std::endl; + } catch(NetSocketPP::SocketException &exc) { + std::cerr << "SocketException occured in NetSocket++: " << exc.what() << "! Skipping..." << std::endl; + } catch(ParseException &exc) { + std::cerr << "ParseException occured: " << exc.what() << "! Skipping..." << std::endl; + } catch(BadResponseException &exc) { + std::cerr << "BadResponseException occured: " << exc.what() << "! Skipping..." << std::endl; + } + } + } + lmodlist.write(); + std::cout << "Sync finished successfully!" << std::endl; + } catch(ParseException &exc) { + std::cerr << "ParseException occured: " << exc.what() << "! Exiting..." << std::endl; + return; + } catch(FileException &exc) { + std::cerr << "FileException occured: " << exc.what() << "! Exiting..." << std::endl; + return; + } +} diff --git a/SyncAction.h b/SyncAction.h new file mode 100644 index 0000000..729e5da --- /dev/null +++ b/SyncAction.h @@ -0,0 +1,33 @@ +#ifndef _SYNCACTION_H +#define _SYNCACTION_H +#include "ConfigFile.h" +#include "3mExceptions.h" +#include "ModListList.h" +#include "ModListDescription.h" +#include "ModInfoDescription.h" +#include "ModDescription.h" +#include "LocalModDescription.h" +#include "ModList.h" +#include "ModInfo.h" +#include "NetSocket++/NetSocketPP.h" +#include "Action.h" +#include +/// \file SyncAction.h +/// \brief A Sync 3m action class. +/// \author Phitherek_ +/// \date 2013 +/// \version 0.1 + +/// \namespace mmm +/// \brief A global namespace for 3m. +namespace mmm { +/// \class SyncAction +/// \brief A Sync 3m action class. +class SyncAction: public Action { +public: + SyncAction(); ///< A constructor. + ~SyncAction(); ///< A destructor. + void run(); ///< A virtual function that executes the action. +}; +} +#endif diff --git a/tests/Makefile b/tests/Makefile index 14cde16..1b1d919 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -8,6 +8,7 @@ all: ${CXX} ${CXXFLAGS} -o RepositoryInfoTest RepositoryInfoTest.cpp ../RepositoryModDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp ../ConfigFile.cpp ../RepositoryInfo.cpp ${CXX} ${CXXFLAGS} -o ModInfoTest ModInfoTest.cpp ../ModInfo.cpp ../ModInfoDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp -lnetsocketpp ${CXX} ${CXXFLAGS} -o ModListTest ModListTest.cpp ../ModList.cpp ../ModListDescription.cpp ../ModInfo.cpp ../ModInfoDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp -lnetsocketpp + ${CXX} ${CXXFLAGS} -o SyncActionTest SyncActionTest.cpp ../SyncAction.cpp ../Action.cpp ../ConfigFile.cpp ../ModListList.cpp ../3mExceptions.cpp ../ModList.cpp ../ModInfo.cpp ../ModListDescription.cpp ../ModInfoDescription.cpp ../ModDescription.cpp ../LocalModDescription.cpp ../LocalModList.cpp -lnetsocketpp debug: ${CXX} ${CXXFLAGS} -o ConfigFileTest ConfigFileTest.cpp ../ConfigFile.cpp ../3mExceptions.cpp -g ${CXX} ${CXXFLAGS} -o ModDescriptionTest ModDescriptionTest.cpp ../ModDescription.cpp -g @@ -17,5 +18,6 @@ debug: ${CXX} ${CXXFLAGS} -o RepositoryInfoTest RepositoryInfoTest.cpp ../RepositoryModDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp ../ConfigFile.cpp ../RepositoryInfo.cpp -g ${CXX} ${CXXFLAGS} -o ModInfoTest ModInfoTest.cpp ../ModInfo.cpp ../ModInfoDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp -lnetsocketpp -g ${CXX} ${CXXFLAGS} -o ModListTest ModListTest.cpp ../ModList.cpp ../ModListDescription.cpp ../ModInfo.cpp ../ModInfoDescription.cpp ../ModDescription.cpp ../3mExceptions.cpp -lnetsocketpp -g + ${CXX} ${CXXFLAGS} -o SyncActionTest SyncActionTest.cpp ../SyncAction.cpp ../Action.cpp ../ConfigFile.cpp ../ModListList.cpp ../3mExceptions.cpp ../ModList.cpp ../ModInfo.cpp ../ModListDescription.cpp ../ModInfoDescription.cpp ../ModDescription.cpp ../LocalModDescription.cpp ../LocalModList.cpp -lnetsocketpp -g clean: - rm -rf ConfigFileTest ModDescriptionTest LocalModDescriptionTest ModListListTest LocalModListTest RepositoryInfoTest ModInfoTest ModListTest + rm -rf ConfigFileTest ModDescriptionTest LocalModDescriptionTest ModListListTest LocalModListTest RepositoryInfoTest ModInfoTest ModListTest SyncActionTest diff --git a/tests/SyncActionTest.cpp b/tests/SyncActionTest.cpp new file mode 100644 index 0000000..62b1ae7 --- /dev/null +++ b/tests/SyncActionTest.cpp @@ -0,0 +1,17 @@ +#include "../SyncAction.h" +#include +#include +using namespace std; + +int main(int argc, char** argv) { + mmm::SyncAction act; + if(argc > 1) { + for(int i = 1; i < argc; i++) { + std::string arg = ""; + arg += argv[i]; + act.insertParameter(arg); + } + } + act.run(); + return EXIT_SUCCESS; +}