From 41aa40e1e2a14815305169a82cd3382e4f5bac84 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 4 Jan 2017 17:11:13 +0100 Subject: [PATCH] feat(app): - rename `Database` class to `Paths` - use linphone logger - better log format when the app is compiled in debug mode - use the log collection of linphone --- tests/CMakeLists.txt | 6 +- tests/src/app/AvatarProvider.cpp | 4 +- tests/src/app/Database.cpp | 77 ----------- tests/src/app/Database.hpp | 20 --- tests/src/app/Logger.cpp | 137 +++++++++++++++----- tests/src/app/Logger.hpp | 12 +- tests/src/app/Paths.cpp | 89 +++++++++++++ tests/src/app/Paths.hpp | 17 +++ tests/src/components/contact/VcardModel.cpp | 8 +- tests/src/components/core/CoreManager.cpp | 26 +--- tests/src/main.cpp | 4 +- 11 files changed, 235 insertions(+), 165 deletions(-) delete mode 100644 tests/src/app/Database.cpp delete mode 100644 tests/src/app/Database.hpp create mode 100644 tests/src/app/Paths.cpp create mode 100644 tests/src/app/Paths.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bfbde2f4c..14aca3a33 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -46,16 +46,18 @@ foreach (package ${QT5_PACKAGES}) endif () endforeach () +list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/liblinphone.so") list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/liblinphone++.so") list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/libbelcard.so") list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/libbellesip.so") +list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/libbctoolbox.so") set(SOURCES src/app/App.cpp src/app/AvatarProvider.cpp - src/app/Database.cpp src/app/DefaultTranslator.cpp src/app/Logger.cpp + src/app/Paths.cpp src/components/camera/Camera.cpp src/components/chat/ChatModel.cpp src/components/chat/ChatProxyModel.cpp @@ -78,9 +80,9 @@ set(SOURCES set(HEADERS src/app/App.hpp src/app/AvatarProvider.hpp - src/app/Database.hpp src/app/DefaultTranslator.hpp src/app/Logger.hpp + src/app/Paths.hpp src/components/camera/Camera.hpp src/components/chat/ChatModel.hpp src/components/chat/ChatProxyModel.hpp diff --git a/tests/src/app/AvatarProvider.cpp b/tests/src/app/AvatarProvider.cpp index f54d8e309..f0d05b604 100644 --- a/tests/src/app/AvatarProvider.cpp +++ b/tests/src/app/AvatarProvider.cpp @@ -1,4 +1,4 @@ -#include "Database.hpp" +#include "Paths.hpp" #include "../utils.hpp" #include "AvatarProvider.hpp" @@ -12,7 +12,7 @@ AvatarProvider::AvatarProvider () : QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading ) { - m_avatars_path = Utils::linphoneStringToQString(Database::getAvatarsPath()); + m_avatars_path = Utils::linphoneStringToQString(Paths::getAvatarsDirpath()); } QImage AvatarProvider::requestImage ( diff --git a/tests/src/app/Database.cpp b/tests/src/app/Database.cpp deleted file mode 100644 index 77beaf4f5..000000000 --- a/tests/src/app/Database.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include - -#include "../utils.hpp" - -#include "Database.hpp" - -// ============================================================================= - -#ifdef _WIN32 - -#define DATABASES_PATH \ - QStandardPaths::writableLocation(QStandardPaths::DataLocation) -#define DATABASE_PATH_CONFIG "linphonerc" - -#else - -#define DATABASES_PATH \ - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) -#define DATABASE_PATH_CONFIG ".linphonerc" - -#endif // ifdef _WIN32 - -#define DATABASE_PATH_AVATARS ".linphone/avatars/" -#define DATABASE_PATH_CALL_HISTORY_LIST ".linphone-call-history.db" -#define DATABASE_PATH_FRIENDS_LIST ".linphone-friends.db" -#define DATABASE_PATH_MESSAGE_HISTORY_LIST ".linphone-history.db" - -using namespace std; - -// ============================================================================= - -inline bool ensureDatabaseFilePathExists (const QString &path) { - QDir dir(DATABASES_PATH); - - if (!dir.exists() && !dir.mkpath(DATABASES_PATH)) - return false; - - QFile file(path); - - return file.exists() || file.open(QIODevice::ReadWrite); -} - -string Database::getAvatarsPath () { - QString path(DATABASES_PATH + "/" DATABASE_PATH_AVATARS); - QDir dir(path); - - if (!dir.exists() && !dir.mkpath(path)) - return ""; - - return Utils::qStringToLinphoneString(QDir::toNativeSeparators(path)); -} - -inline string getDatabaseFilePath (const QString &filename) { - QString path(DATABASES_PATH + "/"); - path += filename; - return ensureDatabaseFilePathExists(path) ? Utils::qStringToLinphoneString( - QDir::toNativeSeparators(path) - ) : ""; -} - -string Database::getCallHistoryPath () { - return getDatabaseFilePath(DATABASE_PATH_CALL_HISTORY_LIST); -} - -string Database::getConfigPath () { - return getDatabaseFilePath(DATABASE_PATH_CONFIG); -} - -string Database::getFriendsListPath () { - return getDatabaseFilePath(DATABASE_PATH_FRIENDS_LIST); -} - -string Database::getMessageHistoryPath () { - return getDatabaseFilePath(DATABASE_PATH_MESSAGE_HISTORY_LIST); -} diff --git a/tests/src/app/Database.hpp b/tests/src/app/Database.hpp deleted file mode 100644 index 7ce912540..000000000 --- a/tests/src/app/Database.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef DATABASE_H_ -#define DATABASE_H_ - -#include - -// ============================================================================= - -namespace Database { - // Returns the databases paths. - // If files cannot be created or are unavailable, a empty string is returned. - // Use the directories separator of used OS. - std::string getAvatarsPath (); - - std::string getCallHistoryPath (); - std::string getConfigPath (); - std::string getFriendsListPath (); - std::string getMessageHistoryPath (); -} - -#endif // DATABASE_H_ diff --git a/tests/src/app/Logger.cpp b/tests/src/app/Logger.cpp index 6b4050202..9c26a948a 100644 --- a/tests/src/app/Logger.cpp +++ b/tests/src/app/Logger.cpp @@ -1,61 +1,126 @@ +#include +#include +#include #include +#include "Paths.hpp" + #include "Logger.hpp" #ifdef __linux__ #define BLUE "\x1B[1;34m" + #define YELLOW "\x1B[1;33m" #define GREEN "\x1B[1;32m" #define PURPLE "\x1B[1;35m" #define RED "\x1B[1;31m" #define RESET "\x1B[0m" #else #define BLUE "" + #define YELLOW "" #define GREEN "" #define PURPLE "" #define RED "" #define RESET "" #endif // ifdef __linux__ +#define QT_DOMAIN "qt" + +#define MAX_LOGS_COLLECTION_SIZE 104857600 /* 100MB. */ + // ============================================================================= -void logger (QtMsgType type, const QMessageLogContext &context, const QString &msg) { +Logger *Logger::m_instance = nullptr; + +// ----------------------------------------------------------------------------- + +static void qtLogger (QtMsgType type, const QMessageLogContext &context, const QString &msg) { + const char *format; + BctbxLogLevel level; + + if (type == QtDebugMsg) { + format = GREEN "[%s][Debug]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_DEBUG; + } else if (type == QtInfoMsg) { + format = BLUE "[%s][Info]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_MESSAGE; + } else if (type == QtWarningMsg) { + format = RED "[%s][Warning]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_WARNING; + } else if (type == QtCriticalMsg) { + format = RED "[%s][Critical]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_ERROR; + } else if (type == QtFatalMsg) { + format = RED "[%s][Fatal]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_FATAL; + } else + return; + + const char *context_str = ""; + + #ifdef QT_MESSAGELOGCONTEXT + QByteArray context_arr = QStringLiteral("%1:%2: ").arg(context.file).arg(context.line).toLocal8Bit(); + context_str = context_arr.constData(); + #endif // ifdef QT_MESSAGELOGCONTEXT + QByteArray local_msg = msg.toLocal8Bit(); - QByteArray date_time = QDateTime::currentDateTime() - .toString("HH:mm:ss").toLocal8Bit(); + QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit(); - const char *context_file = "cpp"; - int context_line = 0; + fprintf(stderr, format, date_time.constData(), context_str, local_msg.constData()); + bctbx_log(QT_DOMAIN, level, "QT: %s%s", context_str, local_msg.constData()); - if (context.file && !context.function) { - context_file = context.file; - context_line = context.line; - } - - if (type == QtDebugMsg) - fprintf( - stderr, GREEN "[%s][Debug]" PURPLE "%s:%u: " RESET "%s\n", - date_time.constData(), context_file, context_line, local_msg.constData() - ); - else if (type == QtInfoMsg) - fprintf( - stderr, BLUE "[%s][Info]" PURPLE "%s:%u: " RESET "%s\n", - date_time.constData(), context_file, context_line, local_msg.constData() - ); - else if (type == QtWarningMsg) - fprintf( - stderr, RED "[%s][Warning]" PURPLE "%s:%u: " RESET "%s\n", - date_time.constData(), context_file, context_line, local_msg.constData() - ); - else if (type == QtCriticalMsg) - fprintf( - stderr, RED "[%s][Critical]" PURPLE "%s:%u: " RESET "%s\n", - date_time.constData(), context_file, context_line, local_msg.constData() - ); - else if (type == QtFatalMsg) { - fprintf( - stderr, RED "[%s][Fatal]" PURPLE "%s:%u: " RESET "%s\n", - date_time.constData(), context_file, context_line, local_msg.constData() - ); + if (type == QtFatalMsg) abort(); - } +} + +// ----------------------------------------------------------------------------- + +static void linphoneLogger (const char *domain, OrtpLogLevel type, const char *fmt, va_list args) { + const char *format; + + if (type == ORTP_DEBUG) + format = GREEN "[%s][Debug]" YELLOW "Core:%s: " RESET "%s\n"; + else if (type == ORTP_TRACE) + format = BLUE "[%s][Trace]" YELLOW "Core:%s: " RESET "%s\n"; + else if (type == ORTP_MESSAGE) + format = BLUE "[%s][Info]" YELLOW "Core:%s: " RESET "%s\n"; + else if (type == ORTP_WARNING) + format = RED "[%s][Warning]" YELLOW "Core:%s: " RESET "%s\n"; + else if (type == ORTP_ERROR) + format = RED "[%s][Critical]" YELLOW "Core:%s: " RESET "%s\n"; + else if (type == ORTP_FATAL) + format = RED "[%s][Fatal]" YELLOW "Core:%s: " RESET "%s\n"; + else + return; + + QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit(); + char *msg = bctbx_strdup_vprintf(fmt, args); + + fprintf(stderr, format, date_time.constData(), domain, msg); + + bctbx_free(msg); + + if (type == ORTP_FATAL) + abort(); +} + +// ----------------------------------------------------------------------------- + +void Logger::init () { + if (m_instance) + return; + m_instance = new Logger(); + + qInstallMessageHandler(qtLogger); + + linphone_core_set_log_level(ORTP_MESSAGE); + linphone_core_set_log_handler( + [](const char *domain, OrtpLogLevel type, const char *fmt, va_list args) { + if (m_instance->m_display_core_logs) + linphoneLogger(domain, type, fmt, args); + } + ); + + linphone_core_set_log_collection_path(Paths::getLogsDirpath().c_str()); + linphone_core_set_log_collection_max_file_size(MAX_LOGS_COLLECTION_SIZE); + linphone_core_enable_log_collection(LinphoneLogCollectionEnabled); } diff --git a/tests/src/app/Logger.hpp b/tests/src/app/Logger.hpp index 4148ee8ab..337d183d0 100644 --- a/tests/src/app/Logger.hpp +++ b/tests/src/app/Logger.hpp @@ -5,6 +5,16 @@ // ============================================================================= -void logger (QtMsgType type, const QMessageLogContext &context, const QString &msg); +class Logger { +public: + static void init (); + +private: + Logger () = default; + + bool m_display_core_logs = false; + + static Logger *m_instance; +}; #endif // LOGGER_H_ diff --git a/tests/src/app/Paths.cpp b/tests/src/app/Paths.cpp new file mode 100644 index 000000000..51ece121e --- /dev/null +++ b/tests/src/app/Paths.cpp @@ -0,0 +1,89 @@ +#include +#include +#include + +#include "../utils.hpp" + +#include "Paths.hpp" + +// ============================================================================= + +#ifdef _WIN32 + +#define MAIN_PATH \ + QStandardPaths::writableLocation(QStandardPaths::DataLocation) +#define PATH_CONFIG "linphonerc" + +#define LINPHONE_FOLDER "linphone/" + +#else + +#define MAIN_PATH \ + QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +#define PATH_CONFIG ".linphonerc" + +#define LINPHONE_FOLDER ".linphone/" + +#endif // ifdef _WIN32 + +#define PATH_AVATARS LINPHONE_FOLDER "avatars/" +#define PATH_LOGS LINPHONE_FOLDER "logs/" + +#define PATH_CALL_HISTORY_LIST ".linphone-call-history.db" +#define PATH_FRIENDS_LIST ".linphone-friends.db" +#define PATH_MESSAGE_HISTORY_LIST ".linphone-history.db" + +using namespace std; + +// ============================================================================= + +inline void ensureDirectoryPathExists (const QString &path) { + QDir dir(path); + if (!dir.exists() && !dir.mkpath(path)) + qFatal("Unable to access at directory: `%s`", path.toStdString().c_str()); +} + +inline void ensureFilePathExists (const QString &path) { + QFileInfo info(path); + ensureDirectoryPathExists(info.path()); + + QFile file(path); + if (!file.exists() && !file.open(QIODevice::ReadWrite)) + qFatal("Unable to access at path: `%s`", path.toStdString().c_str()); +} + +inline string getDirectoryPath (const QString &dirname) { + ensureDirectoryPathExists(dirname); + return Utils::qStringToLinphoneString(QDir::toNativeSeparators(dirname)); +} + +inline string getFilePath (const QString &filename) { + ensureFilePathExists(filename); + return Utils::qStringToLinphoneString(QDir::toNativeSeparators(filename)); +} + +// ----------------------------------------------------------------------------- + +string Paths::getAvatarsDirpath () { + return getDirectoryPath(MAIN_PATH + "/" PATH_AVATARS); +} + +string Paths::getCallHistoryFilepath () { + return getFilePath(MAIN_PATH + "/" + PATH_CALL_HISTORY_LIST); +} + +string Paths::getConfigFilepath () { + return getFilePath(MAIN_PATH + "/" + PATH_CONFIG); +} + +string Paths::getFriendsListFilepath () { + return getFilePath(MAIN_PATH + "/" + PATH_FRIENDS_LIST); +} + +string Paths::getLogsDirpath () { + return getDirectoryPath(MAIN_PATH + "/" PATH_LOGS); +} + +string Paths::getMessageHistoryFilepath () { + return getFilePath(MAIN_PATH + "/" + PATH_MESSAGE_HISTORY_LIST); +} diff --git a/tests/src/app/Paths.hpp b/tests/src/app/Paths.hpp new file mode 100644 index 000000000..85faab4a3 --- /dev/null +++ b/tests/src/app/Paths.hpp @@ -0,0 +1,17 @@ +#ifndef PATHS_H_ +#define PATHS_H_ + +#include + +// ============================================================================= + +namespace Paths { + std::string getAvatarsDirpath (); + std::string getCallHistoryFilepath (); + std::string getConfigFilepath (); + std::string getFriendsListFilepath (); + std::string getLogsDirpath (); + std::string getMessageHistoryFilepath (); +} + +#endif // PATHS_H_ diff --git a/tests/src/components/contact/VcardModel.cpp b/tests/src/components/contact/VcardModel.cpp index 61f6aeaa2..fb565d7d9 100644 --- a/tests/src/components/contact/VcardModel.cpp +++ b/tests/src/components/contact/VcardModel.cpp @@ -5,7 +5,7 @@ #include #include "../../app/App.hpp" -#include "../../app/Database.hpp" +#include "../../app/Paths.hpp" #include "../../utils.hpp" #include "../core/CoreManager.hpp" @@ -57,7 +57,7 @@ VcardModel::~VcardModel () { QString image_path( ::Utils::linphoneStringToQString( - Database::getAvatarsPath() + + Paths::getAvatarsDirpath() + photo->getValue().substr(sizeof(VCARD_SCHEME) - 1) ) ); @@ -111,7 +111,7 @@ bool VcardModel::setAvatar (const QString &path) { .arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`. .arg(info.suffix()); - QString dest = ::Utils::linphoneStringToQString(Database::getAvatarsPath()) + file_id; + QString dest = ::Utils::linphoneStringToQString(Paths::getAvatarsDirpath()) + file_id; if (!file.copy(dest)) return false; @@ -127,7 +127,7 @@ bool VcardModel::setAvatar (const QString &path) { if (old_photo) { QString image_path( ::Utils::linphoneStringToQString( - Database::getAvatarsPath() + old_photo->getValue().substr(sizeof(VCARD_SCHEME) - 1) + Paths::getAvatarsDirpath() + old_photo->getValue().substr(sizeof(VCARD_SCHEME) - 1) ) ); diff --git a/tests/src/components/core/CoreManager.cpp b/tests/src/components/core/CoreManager.cpp index 4f2c50720..183ded8fd 100644 --- a/tests/src/components/core/CoreManager.cpp +++ b/tests/src/components/core/CoreManager.cpp @@ -1,6 +1,6 @@ #include -#include "../../app/Database.hpp" +#include "../../app/Paths.hpp" #include "CoreManager.hpp" @@ -11,10 +11,7 @@ using namespace std; CoreManager *CoreManager::m_instance = nullptr; CoreManager::CoreManager (QObject *parent) : QObject(parent), m_handlers(make_shared()) { - string config_path = Database::getConfigPath(); - if (config_path.length() == 0) - qFatal("Unable to get config path."); - m_core = linphone::Factory::get()->createCore(m_handlers, config_path, ""); + m_core = linphone::Factory::get()->createCore(m_handlers, Paths::getConfigFilepath(), ""); setDatabasesPaths(); } @@ -45,20 +42,7 @@ VcardModel *CoreManager::createDetachedVcardModel () { } void CoreManager::setDatabasesPaths () { - string database_path; - - database_path = Database::getFriendsListPath(); - if (database_path.length() == 0) - qFatal("Unable to get friends list database path."); - m_core->setFriendsDatabasePath(database_path); - - database_path = Database::getCallHistoryPath(); - if (database_path.length() == 0) - qFatal("Unable to get call history database path."); - m_core->setCallLogsDatabasePath(database_path); - - database_path = Database::getMessageHistoryPath(); - if (database_path.length() == 0) - qFatal("Unable to get message history database path."); - m_core->setChatDatabasePath(database_path); + m_core->setFriendsDatabasePath(Paths::getFriendsListFilepath()); + m_core->setCallLogsDatabasePath(Paths::getCallHistoryFilepath()); + m_core->setChatDatabasePath(Paths::getMessageHistoryFilepath()); } diff --git a/tests/src/main.cpp b/tests/src/main.cpp index 909f3c605..442d2e946 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -1,10 +1,10 @@ #include "app/App.hpp" #include "app/Logger.hpp" -// =================================================================== +// ============================================================================= int main (int argc, char *argv[]) { - qInstallMessageHandler(logger); + Logger::init(); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); App::init(argc, argv);