From 7bba87575f6fd688baa8786e4aa1bd4c9892704f Mon Sep 17 00:00:00 2001 From: tastytea Date: Fri, 20 Dec 2019 01:14:23 +0100 Subject: [PATCH] Print --help, --version and implement downloading. --- man/mastorss.1.adoc | 42 ++++++++++++++++++----- src/document.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ src/document.hpp | 44 ++++++++++++++++++++++++ src/exceptions.cpp | 43 +++++++++++++++++++++++ src/exceptions.hpp | 49 ++++++++++++++++++++++++++ src/main.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 329 insertions(+), 8 deletions(-) create mode 100644 src/document.cpp create mode 100644 src/document.hpp create mode 100644 src/exceptions.cpp create mode 100644 src/exceptions.hpp create mode 100644 src/main.cpp diff --git a/man/mastorss.1.adoc b/man/mastorss.1.adoc index 7216dd8..83ca3ea 100644 --- a/man/mastorss.1.adoc +++ b/man/mastorss.1.adoc @@ -2,7 +2,7 @@ :doctype: manpage :Author: tastytea :Email: tastytea@tastytea.de -:Date: 2019-12-16 +:Date: 2019-12-20 :Revision: 0.0.0 :man source: mastorss :man manual: General Commands Manual @@ -13,19 +13,44 @@ mastorss - Another RSS to Mastodon bot. == SYNOPSIS -*mastorss* profile +*mastorss* [--help|--version] // == DESCRIPTION -// == OPTIONS +== OPTIONS + +*--help*:: +Show help message. + +*--version*:: +Show version, copyright and license. // == EXAMPLES -// == PROTOCOL SUPPORT +== PROTOCOL SUPPORT -// Currently only HTTP and HTTPS are supported. +Currently only HTTP and HTTPS are supported. -// == PROXY SUPPORT +// == PROXY SERVERS + +// Since mastorss is built on libcurl, it respects the same proxy environment +// variables. See *curl*(1), section _ENVIRONMENT_. + +// .Tunnel connections through tor. +// ================================================================================ +// [source,shell] +// -------------------------------------------------------------------------------- +// ALL_PROXY="socks4a://[::1]:9050" mastorss example +// -------------------------------------------------------------------------------- +// ================================================================================ + +== PROXY SERVERS + +mastorss supports HTTP proxies set via the environment variable +_http_proxy_. Accepted formats are: _\http://[user[:password]@]host[:port]/_ or +_[user[:password]@]host[:port]_. No SOCKS proxy support yet, sorry. + +Example: `http_proxy="http://localhost:3128/" mastorss` == FILES @@ -39,12 +64,13 @@ mastorss - Another RSS to Mastodon bot. |=========================================================== | Code | Explanation -| 1 | Could not send post for unknown reasons. +| 1 | No profile specified. +| 2 | Network error. |=========================================================== == SEE ALSO -*crontab*(1), *crontab*(5) +*curl*(1), *crontab*(1), *crontab*(5) == REPORTING BUGS diff --git a/src/document.cpp b/src/document.cpp new file mode 100644 index 0000000..0bf97e9 --- /dev/null +++ b/src/document.cpp @@ -0,0 +1,75 @@ +/* This file is part of mastorss. + * Copyright © 2019 tastytea + * + * 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, version 3. + * + * 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 "document.hpp" +#include "exceptions.hpp" +#include "version.hpp" + +#include +#include + +#include +#include + +using namespace mastorss; +using std::string; +using std::move; + +Document::Document(string uri) + : _uri{move(uri)} +{ + RestClient::init(); + + download(); +} + +Document::~Document() +{ + RestClient::disable(); +} + +void Document::download() +{ + RestClient::Connection connection(_uri); + connection.SetUserAgent(string("mastorss/").append(version)); + connection.FollowRedirects(true, 10); + + RestClient::Response response{connection.get("")}; + + switch (response.code) + { + case 200: + { + _raw_doc = response.body; + break; + } + case 301: + case 308: + { + // TODO(tastytea): Handle permanent redirections. + throw std::runtime_error{"Permanent redirect, " + "no solution implemented yet."}; + } + case -1: + { + throw CURLException{errno}; + } + default: + { + throw HTTPException{response.code}; + } + } +} diff --git a/src/document.hpp b/src/document.hpp new file mode 100644 index 0000000..1a5ddf1 --- /dev/null +++ b/src/document.hpp @@ -0,0 +1,44 @@ +/* This file is part of mastorss. + * Copyright © 2019 tastytea + * + * 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, version 3. + * + * 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 . + */ + +#ifndef MASTORSS_DOCUMENT_HPP +#define MASTORSS_DOCUMENT_HPP + +#include + +namespace mastorss +{ +using std::string; + +class Document +{ +public: + explicit Document(string uri); + ~Document(); + Document(const Document &other) = default; + Document &operator=(const Document &other) = delete; + Document(Document &&other) = default; + Document &operator=(Document &&other) = delete; + + void download(); + +private: + const string _uri; + string _raw_doc; +}; +} // namespace mastorss + +#endif // MASTORSS_DOCUMENT_HPP diff --git a/src/exceptions.cpp b/src/exceptions.cpp new file mode 100644 index 0000000..58458b5 --- /dev/null +++ b/src/exceptions.cpp @@ -0,0 +1,43 @@ +/* This file is part of mastorss. + * Copyright © 2019 tastytea + * + * 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, version 3. + * + * 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 "exceptions.hpp" + +#include + +using namespace mastorss; +using std::string; +using std::to_string; + +HTTPException::HTTPException(const int error) + : error_code{static_cast(error)} +{} + +const char *HTTPException::what() const noexcept +{ + static const string error_string{"HTTP error: " + to_string(error_code)}; + return error_string.c_str(); +} + +CURLException::CURLException(const int error) + : error_code{static_cast(error)} +{} + +const char *CURLException::what() const noexcept +{ + static const string error_string{"libCURL error: " + to_string(error_code)}; + return error_string.c_str(); +} diff --git a/src/exceptions.hpp b/src/exceptions.hpp new file mode 100644 index 0000000..aac1c9d --- /dev/null +++ b/src/exceptions.hpp @@ -0,0 +1,49 @@ +/* This file is part of mastorss. + * Copyright © 2019 tastytea + * + * 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, version 3. + * + * 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 . + */ + +#ifndef MASTORSS_EXCEPTIONS_HPP +#define MASTORSS_EXCEPTIONS_HPP + +#include +#include + +namespace mastorss +{ +using std::uint16_t; +using std::exception; + +class HTTPException : public exception +{ +public: + const uint16_t error_code; + + explicit HTTPException(const int error); + + virtual const char *what() const noexcept; +}; + +class CURLException : public exception +{ +public: + const uint16_t error_code; + + explicit CURLException(const int error); + + virtual const char *what() const noexcept; +}; +} // namespace mastorss + +#endif // MASTORSS_EXCEPTIONS_HPP diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..422259e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,84 @@ +#include "version.hpp" +#include "document.hpp" +#include "exceptions.hpp" + +#include +#include +#include + +using namespace mastorss; +using std::cout; +using std::cerr; +using std::string_view; +using std::vector; + +namespace mastorss +{ +namespace error +{ +constexpr int noprofile = 1; +constexpr int network = 2; +} // namespace error + +void print_version(); +void print_help(const string_view &command); + +void print_version() +{ + cout << "mastorss " << version << "\n" + "Copyright (C) 2019 tastytea \n" + "License GPLv3: GNU GPL version 3 " + ".\n" + "This program comes with ABSOLUTELY NO WARRANTY. " + "This is free software,\n" + "and you are welcome to redistribute it under certain conditions.\n"; +} + +void print_help(const string_view &command) +{ + cerr << "Usage: " << command << " [--version] \n"; +} +} // namespace mastorss + +int main(int argc, char *argv[]) +{ + const vector args(argv, argv + argc); + + if (args.size() == 1) + { + print_help(args[0]); + return error::noprofile; + } + + if (args.size() > 1) + { + if (args[1] == "--version") + { + print_version(); + } + else if (args[1] == "--help") + { + print_help(args[0]); + } + else + { + try + { + Document doc("https://ip.tastytea.de/"); + } + catch (const HTTPException &e) + { + cerr << e.what() << '\n'; + return error::network; + } + catch (const CURLException &e) + { + cerr << e.what() << '\n'; + return error::network; + } + + } + } + + return 0; +}