mirror of
https://github.com/Sude-/lgogdownloader.git
synced 2024-11-20 11:49:17 +01:00
Add "Message" class
Changed message queue to use the new "Message" class. Simplifies status message printing by having the message class take care of formatting and keeping track of the message type. Status messages are now timestamped and colored based on message type
This commit is contained in:
parent
0dfa610c28
commit
fb565f4493
108
include/message.h
Normal file
108
include/message.h
Normal file
@ -0,0 +1,108 @@
|
||||
/* This program is free software. It comes without any warranty, to
|
||||
* the extent permitted by applicable law. You can redistribute it
|
||||
* and/or modify it under the terms of the Do What The Fuck You Want
|
||||
* To Public License, Version 2, as published by Sam Hocevar. See
|
||||
* http://www.wtfpl.net/ for more details. */
|
||||
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
const unsigned int MSGTYPE_INFO = 1 << 0;
|
||||
const unsigned int MSGTYPE_WARNING = 1 << 1;
|
||||
const unsigned int MSGTYPE_ERROR = 1 << 2;
|
||||
const unsigned int MSGTYPE_SUCCESS = 1 << 3;
|
||||
|
||||
class Message
|
||||
{
|
||||
public:
|
||||
Message() = default;
|
||||
Message(std::string msg, const unsigned int& type = MSGTYPE_INFO, const std::string& prefix = std::string())
|
||||
{
|
||||
prefix_ = prefix;
|
||||
msg_ = msg;
|
||||
type_ = type;
|
||||
timestamp_ = boost::posix_time::second_clock::local_time();
|
||||
}
|
||||
|
||||
void setMessage(const std::string& msg)
|
||||
{
|
||||
msg_ = msg;
|
||||
}
|
||||
|
||||
void setType(const unsigned int& type)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
void setTimestamp(const boost::posix_time::ptime& timestamp)
|
||||
{
|
||||
timestamp_ = timestamp;
|
||||
}
|
||||
|
||||
void setPrefix(const std::string& prefix)
|
||||
{
|
||||
prefix_ = prefix;
|
||||
}
|
||||
|
||||
std::string getMessage()
|
||||
{
|
||||
return msg_;
|
||||
}
|
||||
|
||||
unsigned int getType()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
boost::posix_time::ptime getTimestamp()
|
||||
{
|
||||
return timestamp_;
|
||||
}
|
||||
|
||||
std::string getTimestampString()
|
||||
{
|
||||
return boost::posix_time::to_simple_string(timestamp_);
|
||||
}
|
||||
|
||||
std::string getPrefix()
|
||||
{
|
||||
return prefix_;
|
||||
}
|
||||
|
||||
std::string getFormattedString(const bool& bColor = true, const bool& bPrefix = true)
|
||||
{
|
||||
std::string str;
|
||||
std::string color_value = "\033[39m"; // Default foreground color
|
||||
std::string color_reset = "\033[0m";
|
||||
|
||||
if (type_ == MSGTYPE_INFO)
|
||||
color_value = "\033[39m"; // Default foreground color
|
||||
else if (type_ == MSGTYPE_WARNING)
|
||||
color_value = "\033[33m"; // Yellow
|
||||
else if (type_ == MSGTYPE_ERROR)
|
||||
color_value = "\033[31m"; // Red
|
||||
else if (type_ == MSGTYPE_SUCCESS)
|
||||
color_value = "\033[32m"; // Green
|
||||
|
||||
str = msg_;
|
||||
if (!prefix_.empty() && bPrefix)
|
||||
str = prefix_ + " " + str;
|
||||
|
||||
str = getTimestampString() + " " + str;
|
||||
|
||||
if (bColor)
|
||||
str = color_value + str + color_reset;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string msg_;
|
||||
boost::posix_time::ptime timestamp_;
|
||||
unsigned int type_;
|
||||
std::string prefix_;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_H
|
2
main.cpp
2
main.cpp
@ -156,7 +156,7 @@ int main(int argc, char *argv[])
|
||||
("language", bpo::value<std::string>(&sInstallerLanguage)->default_value("en"), language_text.c_str())
|
||||
("no-remote-xml", bpo::value<bool>(&bNoRemoteXML)->zero_tokens()->default_value(false), "Don't use remote XML for repair")
|
||||
("no-unicode", bpo::value<bool>(&bNoUnicode)->zero_tokens()->default_value(false), "Don't use Unicode in the progress bar")
|
||||
("no-color", bpo::value<bool>(&bNoColor)->zero_tokens()->default_value(false), "Don't use coloring in the progress bar")
|
||||
("no-color", bpo::value<bool>(&bNoColor)->zero_tokens()->default_value(false), "Don't use coloring in the progress bar or status messages")
|
||||
("no-duplicate-handling", bpo::value<bool>(&bNoDuplicateHandler)->zero_tokens()->default_value(false), "Don't use duplicate handler for installers\nDuplicate installers from different languages are handled separately")
|
||||
("no-subdirectories", bpo::value<bool>(&bNoSubDirectories)->zero_tokens()->default_value(false), "Don't create subdirectories for extras, patches and language packs")
|
||||
("verbose", bpo::value<bool>(&config.bVerbose)->zero_tokens()->default_value(false), "Print lots of information")
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "globalconstants.h"
|
||||
#include "ssl_thread_setup.h"
|
||||
#include "downloadinfo.h"
|
||||
#include "message.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
@ -31,7 +32,7 @@ namespace bptime = boost::posix_time;
|
||||
|
||||
std::vector<DownloadInfo> vDownloadInfo;
|
||||
ThreadSafeQueue<gameFile> dlQueue;
|
||||
ThreadSafeQueue<std::string> msgQueue;
|
||||
ThreadSafeQueue<Message> msgQueue;
|
||||
ThreadSafeQueue<gameFile> createXMLQueue;
|
||||
|
||||
Downloader::Downloader(Config &conf)
|
||||
@ -2883,7 +2884,7 @@ void Downloader::showWishlist()
|
||||
|
||||
void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
{
|
||||
std::string msg_prefix = "[Thread #" + std::to_string(tid) + "] ";
|
||||
std::string msg_prefix = "[Thread #" + std::to_string(tid) + "]";
|
||||
|
||||
API* api = new API(conf.sToken, conf.sSecret);
|
||||
api->curlSetOpt(CURLOPT_SSL_VERIFYPEER, conf.bVerifyPeer);
|
||||
@ -2894,7 +2895,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
if (!api->init())
|
||||
{
|
||||
delete api;
|
||||
msgQueue.push(msg_prefix + "API init failed");
|
||||
msgQueue.push(Message("API init failed", MSGTYPE_ERROR, msg_prefix));
|
||||
vDownloadInfo[tid].setStatus(DLSTATUS_FINISHED);
|
||||
return;
|
||||
}
|
||||
@ -2943,8 +2944,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
// Skip blacklisted files
|
||||
if (conf.blacklist.isBlacklisted(filepath.string()))
|
||||
{
|
||||
if (conf.bVerbose)
|
||||
msgQueue.push(msg_prefix + "Skipped blacklisted file: " + filepath.string());
|
||||
msgQueue.push(Message("Blacklisted file: " + filepath.string(), MSGTYPE_INFO, msg_prefix));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2953,14 +2953,14 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
boost::filesystem::path local_xml_file = xml_directory + "/" + filenameXML;
|
||||
|
||||
vDownloadInfo[tid].setFilename(filepath.filename().string());
|
||||
msgQueue.push(msg_prefix + "Starting download: " + filepath.filename().string());
|
||||
msgQueue.push(Message("Begin download: " + filepath.filename().string(), MSGTYPE_INFO, msg_prefix));
|
||||
|
||||
// Check that directory exists and create subdirectories
|
||||
if (boost::filesystem::exists(directory))
|
||||
{
|
||||
if (!boost::filesystem::is_directory(directory))
|
||||
{
|
||||
msgQueue.push(msg_prefix + directory.string() + " is not directory");
|
||||
msgQueue.push(Message(directory.string() + " is not directory", MSGTYPE_WARNING, msg_prefix));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -2968,7 +2968,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
{
|
||||
if (!boost::filesystem::create_directories(directory))
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Failed to create directory: " + directory.string());
|
||||
msgQueue.push(Message("Failed to create directory: " + directory.string(), MSGTYPE_ERROR, msg_prefix));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -2982,7 +2982,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
xml = api->getXML(gf.gamename, gf.id);
|
||||
if (api->getError())
|
||||
{
|
||||
msgQueue.push(msg_prefix + api->getErrorMessage());
|
||||
msgQueue.push(Message(api->getErrorMessage(), MSGTYPE_ERROR, msg_prefix));
|
||||
api->clearError();
|
||||
}
|
||||
else
|
||||
@ -3016,14 +3016,14 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
}
|
||||
else
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Remote file is different, renaming local file");
|
||||
msgQueue.push(Message("Remote file is different, renaming local file", MSGTYPE_INFO, msg_prefix));
|
||||
std::string date_old = "." + bptime::to_iso_string(bptime::second_clock::local_time()) + ".old";
|
||||
boost::filesystem::path new_name = filepath.string() + date_old; // Rename old file by appending date and ".old" to filename
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::rename(filepath, new_name, ec); // Rename the file
|
||||
if (ec)
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Failed to rename " + filepath.string() + " to " + new_name.string() + "\nSkipping file");
|
||||
msgQueue.push(Message("Failed to rename " + filepath.string() + " to " + new_name.string() + " - Skipping file", MSGTYPE_WARNING, msg_prefix));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -3040,14 +3040,14 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
{
|
||||
if (!boost::filesystem::is_directory(path))
|
||||
{
|
||||
msgQueue.push(msg_prefix + path.string() + " is not directory");
|
||||
msgQueue.push(Message(path.string() + " is not directory", MSGTYPE_WARNING, msg_prefix));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!boost::filesystem::create_directories(path))
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Failed to create directory: " + path.string());
|
||||
msgQueue.push(Message("Failed to create directory: " + path.string(), MSGTYPE_ERROR, msg_prefix));
|
||||
}
|
||||
}
|
||||
std::ofstream ofs(local_xml_file.string().c_str());
|
||||
@ -3058,7 +3058,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
}
|
||||
else
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Can't create " + local_xml_file.string());
|
||||
msgQueue.push(Message("Can't create " + local_xml_file.string(), MSGTYPE_ERROR, msg_prefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3078,7 +3078,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
|
||||
if (api->getError())
|
||||
{
|
||||
msgQueue.push(msg_prefix + api->getErrorMessage());
|
||||
msgQueue.push(Message(api->getErrorMessage(), MSGTYPE_ERROR, msg_prefix));
|
||||
api->clearError();
|
||||
continue;
|
||||
}
|
||||
@ -3087,7 +3087,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
do
|
||||
{
|
||||
if (iRetryCount != 0)
|
||||
msgQueue.push(msg_prefix + "Retry " + std::to_string(iRetryCount) + "/" + std::to_string(conf.iRetries) + ": " + filepath.filename().string());
|
||||
msgQueue.push(Message("Retry " + std::to_string(iRetryCount) + "/" + std::to_string(conf.iRetries) + ": " + filepath.filename().string(), MSGTYPE_INFO, msg_prefix));
|
||||
|
||||
FILE* outfile;
|
||||
// File exists, resume
|
||||
@ -3102,7 +3102,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
}
|
||||
else
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Failed to open " + filepath.string());
|
||||
msgQueue.push(Message("Failed to open " + filepath.string(), MSGTYPE_ERROR, msg_prefix));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3115,7 +3115,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
}
|
||||
else
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Failed to create " + filepath.string());
|
||||
msgQueue.push(Message("Failed to create " + filepath.string(), MSGTYPE_ERROR, msg_prefix));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3158,11 +3158,11 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
}
|
||||
dlrate_avg << std::setprecision(2) << std::fixed << progress_info.rate_avg << rate_unit;
|
||||
|
||||
msgQueue.push(msg_prefix + "Finished download: " + filepath.filename().string() + " (@ " + dlrate_avg.str() + ")");
|
||||
msgQueue.push(Message("Download complete: " + filepath.filename().string() + " (@ " + dlrate_avg.str() + ")", MSGTYPE_SUCCESS, msg_prefix));
|
||||
}
|
||||
else
|
||||
{
|
||||
msgQueue.push(msg_prefix + "Finished download (" + static_cast<std::string>(curl_easy_strerror(result)) + "): " + filepath.filename().string());
|
||||
msgQueue.push(Message("Download complete (" + static_cast<std::string>(curl_easy_strerror(result)) + "): " + filepath.filename().string(), MSGTYPE_WARNING, msg_prefix));
|
||||
|
||||
// Delete the file if download failed and was not a resume attempt or the result is zero length file
|
||||
if (boost::filesystem::exists(filepath) && boost::filesystem::is_regular_file(filepath))
|
||||
@ -3170,7 +3170,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
if ((result != CURLE_PARTIAL_FILE && !bResume && result != CURLE_OPERATION_TIMEDOUT) || boost::filesystem::file_size(filepath) == 0)
|
||||
{
|
||||
if (!boost::filesystem::remove(filepath))
|
||||
msgQueue.push(msg_prefix + "Failed to delete " + filepath.filename().string());
|
||||
msgQueue.push(Message("Failed to delete " + filepath.filename().string(), MSGTYPE_ERROR, msg_prefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3190,7 +3190,7 @@ void Downloader::processDownloadQueue(Config conf, const unsigned int& tid)
|
||||
delete api;
|
||||
|
||||
vDownloadInfo[tid].setStatus(DLSTATUS_FINISHED);
|
||||
msgQueue.push(msg_prefix + "Finished all tasks");
|
||||
msgQueue.push(Message("Finished all tasks", MSGTYPE_INFO, msg_prefix));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -3260,13 +3260,13 @@ void Downloader::printProgress()
|
||||
std::cout << "\033[J\r" << std::flush; // Clear screen from the current line down to the bottom of the screen
|
||||
|
||||
// Print messages from message queue first
|
||||
std::string msg;
|
||||
Message msg;
|
||||
while (msgQueue.try_pop(msg))
|
||||
{
|
||||
std::cout << msg << std::endl;
|
||||
std::cout << msg.getFormattedString(config.bColor, true) << std::endl;
|
||||
if (config.bReport)
|
||||
{
|
||||
this->report_ofs << bptime::to_simple_string(bptime::second_clock::local_time()) << ": " << msg << std::endl;
|
||||
this->report_ofs << msg.getTimestampString() << ": " << msg.getMessage() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user