diff --git a/src/Redmine-CLI/Command/MyAccount.cpp b/src/Redmine-CLI/Command/MyAccount.cpp new file mode 100644 index 0000000..faae5b2 --- /dev/null +++ b/src/Redmine-CLI/Command/MyAccount.cpp @@ -0,0 +1,178 @@ +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include "Redmine/API.hpp" +#include "Redmine/User.hpp" +#include "nlohmann/json_fwd.hpp" + + +Command::MyAccount::MyAccount(RedmineCLI::Redmine *r) +: +redmine_(r), +output_(TEXT) +{ + + CLI::App* myAccount = redmine_->getCLI().add_subcommand("myaccount", + "Api Calls on the account of the token owner"); + + + + myAccountGet = myAccount->add_subcommand("get", "Get the current information of the token owner"); + myAccountGet->needs(redmine_->getTokenOption())->needs(redmine_->getUrlOption()); + myAccountGet->callback([&](){get_();}); + myAccountGet->add_option("-f,--fields", fields_, "The fields of the user object to print. Supported: firstname, lastname, login, id, mail"); + myAccountGet->add_option("-o,--output", output_, "The Output Format to use. Supported: TEXT, YAML")->transform(CLI::CheckedTransformer(outputMap, CLI::ignore_case)); + + myAccountSet = myAccount->add_subcommand("set", "Set the current information of the token owner"); + myAccountSet->needs(redmine_->getTokenOption())->needs(redmine_->getUrlOption()); + myAccountSet->add_option("-f,--firstname", firstname_, "the new firstname"); + myAccountSet->add_option("-l,--lastname", lastname_, "the new lastname"); + myAccountSet->add_option("-a,--login", login_, "the new login"); + myAccountSet->add_option("-m,--mail", mail_, "the new email address"); + myAccountSet->callback([&](){set_();}); +} + +void Command::MyAccount::set_() const +{ + Redmine::API client{redmine_->getUrl(), redmine_->getToken()}; + + Redmine::User user = client.getMyAccount(); + + if (! firstname_.empty()) + { + user.setFirstName(firstname_); + } + + if (! lastname_.empty()) + { + user.setLastName(lastname_); + } + + if (! login_.empty()) + { + user.setLogin(login_); + } + + if (! id_.empty()) + { + user.setId(id_); + } + + if (! mail_.empty()) + { + user.setMail(mail_); + } + + client.setMyAccount(user); + +} + + + +void Command::MyAccount::get_() const +{ + + Redmine::API client{redmine_->getUrl(), redmine_->getToken()}; + + Redmine::User user = client.getMyAccount(); + + bool hasFirstname = std::find(fields_.begin(), fields_.end(),"firstname") + != fields_.end() || fields_.empty(); + + bool hasLastname = std::find(fields_.begin(), fields_.end(),"lastname") + != fields_.end() || fields_.empty(); + + bool hasLogin = std::find(fields_.begin(), fields_.end(),"login") + != fields_.end() || fields_.empty(); + + bool hasId = std::find(fields_.begin(), fields_.end(),"id") + != fields_.end() || fields_.empty(); + + bool hasMail = std::find(fields_.begin(), fields_.end(),"mail") + != fields_.end() || fields_.empty(); + + + nlohmann::json data; + + if (hasFirstname) + { + if (output_ == TEXT) + { + std::cout << "Firstname : " << user.getFirstName() << std::endl; + } + else if (output_ == YAML) + { + data["firstname"]=user.getFirstName(); + } + } + + if (hasLastname) + { + if (output_ == TEXT) + { + std::cout << "Lastname : " << user.getLastName() << std::endl; + } + else if (output_ == YAML) + { + data["lastname"]=user.getLastName(); + } + } + + if (hasLogin) + { + if (output_ == TEXT) + { + std::cout << "Login : " << user.getLogin() << std::endl; + } + else if (output_ == YAML) + { + data["login"]=user.getLogin(); + } + } + + if (hasId) + { + if (output_ == TEXT) + { + std::cout << "Id : " << user.getId() << std::endl; + } + else if (output_ == YAML) + { + data["id"]=user.getId(); + } + } + + if (hasMail) + { + if (output_ == TEXT) + { + std::cout << "Email : " << user.getEmail() << std::endl; + } + else if (output_ == YAML) + { + data["mail"]=user.getEmail(); + } + } + + if (output_ == YAML) + { + std::cout << data.dump(1); + } + +} \ No newline at end of file diff --git a/src/Redmine-CLI/Command/MyAccount.hpp b/src/Redmine-CLI/Command/MyAccount.hpp new file mode 100644 index 0000000..5bf0da2 --- /dev/null +++ b/src/Redmine-CLI/Command/MyAccount.hpp @@ -0,0 +1,105 @@ +#pragma once +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ +#include +#include +#include +#include +#include +#include +#define LOGURU_WITH_STREAMS 1 +#include +#include + + +// forward declaration +namespace RedmineCLI +{ + class Redmine; +}; + +namespace Command +{ + + /** + * @brief class for processing the CLI11 parsed command lines + * + */ + class MyAccount + { + + private: + + /// the main redmine cli application context + RedmineCLI::Redmine *redmine_; + + /// enum for identifying supported output types + enum outputType : std::uint16_t + { + /// output is just text + TEXT, + /// output is yaml + YAML + }; + std::map outputMap{{"text", TEXT}, {"yaml", YAML}}; + + /// pointer to the get subcommand + CLI::App* myAccountGet; + + /// pointer to the set subcommand + CLI::App* myAccountSet; + + /// vector to hold requested attribute fields + std::vector fields_; + + /// requested output type + outputType output_; + + /// the actual implementation of the information get + void get_() const; + + /// the actual implementation of the information set + void set_() const; + + /// parameter for setting the firstname + std::string firstname_; + + /// parameter for setting the lastname + std::string lastname_; + + /// parameter for setting the login + std::string login_; + + /// parameter for setting the id + std::string id_; + + /// parameter for setting the email + std::string mail_; + + + + public: + /** + * @brief Construct a new CLIProcessor object + * + */ + MyAccount(RedmineCLI::Redmine *r); + + + }; // class MyAccount + +}; // namespace Command \ No newline at end of file diff --git a/src/Redmine-CLI/Command/Version.cpp b/src/Redmine-CLI/Command/Version.cpp new file mode 100644 index 0000000..83db1c1 --- /dev/null +++ b/src/Redmine-CLI/Command/Version.cpp @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ +#include +#include +#include "Redmine/User.hpp" +#include "config.hpp" +#include + +Command::Version::Version(RedmineCLI::Redmine *r) +: +redmine_(r), +version_(nullptr) +{ + + version_ = redmine_->getCLI().add_subcommand("version", "Print current program version"); + version_->callback( [&](){ + std::cout << "redmine-api-client Version " << PROJECT_VERSION << std::endl; + }); + + + +} \ No newline at end of file diff --git a/src/Redmine-CLI/Command/Version.hpp b/src/Redmine-CLI/Command/Version.hpp new file mode 100644 index 0000000..a31db62 --- /dev/null +++ b/src/Redmine-CLI/Command/Version.hpp @@ -0,0 +1,62 @@ +#pragma once +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ +#include +#include +#include +#include +#define LOGURU_WITH_STREAMS 1 +#include +#include + +// forward declaration +namespace RedmineCLI +{ + class Redmine; +}; + +namespace Command +{ + + /** + * @brief Command for printing the version of the redmine-cli + * + */ + class Version + { + + private: + + /// the main redmine cli application context + RedmineCLI::Redmine *redmine_; + + /// pointer to the version subcommand + CLI::App* version_; + + public: + /** + * @brief Construct a new CLIProcessor object + * + * @param redmineURL - the url to the redmine instance + * @param apiToken - the token to authenticate api requests + */ + Version(RedmineCLI::Redmine *r); + + + }; // class Version + +}; // namespace Command \ No newline at end of file diff --git a/src/Redmine-CLI/Redmine.cpp b/src/Redmine-CLI/Redmine.cpp new file mode 100644 index 0000000..233608e --- /dev/null +++ b/src/Redmine-CLI/Redmine.cpp @@ -0,0 +1,38 @@ +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ +#include +#include "Redmine-CLI/Command/Version.hpp" +#include +#include + +RedmineCLI::Redmine::Redmine(CLI::App &cli) +: +cli_(cli), +version_(nullptr) +{ + + CLIredmineApiToken_ = cli_.add_option("-t,--token",redmineApiToken_, + "The API token for accessing redmine")->envname("REDMINE_API_TOKEN"); + + CLIredmineUrl_ = cli_.add_option("-u,--url",redmineUrl_,"The URL to the redmine server (e.g. https://redmine.org)")->envname("REDMINE_URL"); + + + // add all commands here + version_ = std::make_unique(this); + myAccount_ = std::make_unique(this); + +} \ No newline at end of file diff --git a/src/Redmine-CLI/Redmine.hpp b/src/Redmine-CLI/Redmine.hpp new file mode 100644 index 0000000..cbabe49 --- /dev/null +++ b/src/Redmine-CLI/Redmine.hpp @@ -0,0 +1,108 @@ +#pragma once +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ +#include "Redmine-CLI/Command/MyAccount.hpp" +#include "Redmine-CLI/Command/Version.hpp" +#include +#include +#include + +namespace RedmineCLI +{ + + /** + * @brief Main class for the CLI appication + * + * This class holds the main CLI::APP context and + * initializes commands for the application. + * + */ + class Redmine + { + private: + + /// Main CLI11 application context + CLI::App &cli_; + + /// CLI option for getting the redmine api token + CLI::Option *CLIredmineApiToken_; + + /// CLI option for getting the redmine url + CLI::Option *CLIredmineUrl_; + + /// the redmine api token itself + std::string redmineApiToken_; + + /// the redmine url itself + std::string redmineUrl_; + + /// pointer to the version subcommand + std::unique_ptr version_; + + /// pointer to the myAccount subcommand + std::unique_ptr myAccount_; + + public: + + /** + * @brief Main constructor for just creating an object and providing the main CLI::App Context + * + * @param cli - the CLI::App context + */ + explicit Redmine(CLI::App &cli); + + /** + * @brief return the CLI::App context as a reference + * + * @return CLI::App& + */ + CLI::App & getCLI() const {return cli_;} + + /** + * @brief Return a pointer to the CLI::Option for the redmine app token + * + * This is helpful as you can make it needed in a subcommand of the application. + * + * @return CLI::Option* + */ + CLI::Option* getTokenOption() { return CLIredmineApiToken_;} + + /** + * @brief Return a pointer to the CLI::Option for the redmine url + * + * This is helpful as you can make it needed in a subcommand of the application. + * + * @return CLI::Option* + */ + CLI::Option* getUrlOption() { return CLIredmineUrl_;} + + /** + * @brief return the parsed app token + * + * @return std::string + */ + std::string getToken() {return redmineApiToken_;} + + /** + * @brief return the parsed redmine url + * + * @return std::string + */ + std::string getUrl() {return redmineUrl_;} + + }; // class Redmine +}; // namespace RedmineCLI \ No newline at end of file diff --git a/src/Redmine-CLI/main.cpp b/src/Redmine-CLI/main.cpp new file mode 100644 index 0000000..89602d4 --- /dev/null +++ b/src/Redmine-CLI/main.cpp @@ -0,0 +1,41 @@ +/* +* Copyright (C) 2024 Dominik Meyer +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include "Redmine-CLI/Redmine.hpp" +#include "config.hpp" +#include "config.hpp.in" +#include +#include +#include +#include +#include +#include +#define LOGURU_WITH_STREAMS 1 +#include +#include + +int main(int argc, char **argv) +{ + + CLI::App app("A command line client for the redmine project management server"); + + RedmineCLI::Redmine redmineCli{app}; + + CLI11_PARSE(app, argc, argv); + + +} \ No newline at end of file