/* This file is part of gitea2rss. * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "version.hpp" using std::cout; using std::cerr; using std::endl; using std::string; using std::ostringstream; using std::stringstream; using std::uint16_t; using std::chrono::system_clock; namespace curlopts = curlpp::options; // Fetch HTTP document. const string get_http(const string &url) { string answer; try { ostringstream oss; curlpp::Easy request; request.setOpt(url); request.setOpt(string("gitea2rss/") + global::version); request.setOpt({ "Connection: close" }); request.setOpt(true); request.setOpt(&oss); request.perform(); uint16_t ret = curlpp::infos::ResponseCode::get(request); if (ret == 200 || ret == 302 || ret == 307 || ret == 301 || ret == 308) { answer = oss.str(); } else { cerr << "HTTP error: " << std::to_string(ret) << endl; } } catch (const std::exception &e) { cerr << "Error: " << e.what() << endl; } return answer; } // Convert time_point to RFC 822 compliant time string. const string strtime(const system_clock::time_point &timepoint) { constexpr uint16_t bufsize = 1024; std::time_t time = system_clock::to_time_t(timepoint); std::tm *timeinfo; timeinfo = std::localtime(&time); char buffer[bufsize]; std::strftime(buffer, bufsize, "%a, %d %b %Y %T %z", timeinfo); return static_cast(buffer); } // Convert ISO 8601 time string to RFC 822 time string. const string strtime(const string &time) { std::tm tm = {}; std::stringstream ss(time); ss >> std::get_time(&tm, "%Y-%m-%dT%T%z"); return strtime(std::chrono::system_clock::from_time_t(std::mktime(&tm))); } int main(int argc, char *argv[]) { const char *envquery = std::getenv("QUERY_STRING"); string url; if (envquery != nullptr) { const string query = envquery; const char *envbaseurl = std::getenv("GITEA2RSS_BASEURL"); if (envbaseurl == nullptr) { return 1; } url = string(envbaseurl) + "/" + query.substr(query.find('=') + 1); // cout << "Content-Type: application/rss+xml\n\n"; cout << "Content-Type: text/plain\n\n"; } else if (argc < 2) { cerr << "usage: " << argv[0] << " URL of Gitea project\n"; return 1; } else { url = argv[1]; } curlpp::initialize(); size_t pos_repo = url.find('/', 8) + 1; const string baseurl = url.substr(0, pos_repo - 1); const string domain = baseurl.substr(baseurl.rfind('/') + 1); const string repo = url.substr(pos_repo); const string project = repo.substr(repo.find('/') + 1); const string now = strtime(system_clock::now()); stringstream data(get_http(baseurl + "/api/v1/repos/" + repo + "/releases")); Json::Value json; data >> json; cout << "\n" " \n" " " << project << " releases\n" " " << url << "\n" " Releases of " << repo << "\n" " gitea2rss " << global::version << "\n" " " << now << "\n"; for (const Json::Value &release : json) { const bool prerelease = release["prerelease"].asBool(); const string type = (prerelease ? "Pre-Release" : "Stable"); cout << " \n" " " << project << ": " << release["name"].asString() << "\n" " " << baseurl << "/" << repo << "/releases\n" " " << domain << " release " << release["id"].asString() << "\n" " " << strtime(release["published_at"].asString()) << "\n" " " << type << "

" << "
\n" << release["body"].asString()
             << "\n
]]>
\n"; // for (const Json::Value &file : release["assets"]) // { // cout << " \n"; // } cout << "
\n"; } cout << "
\n" "
\n"; return 0; }