Commit 41aa40e1 authored by Ronan Abhamon's avatar Ronan Abhamon

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
parent f0a4652c
......@@ -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
......
#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 (
......
#include <QDir>
#include <QFile>
#include <QStandardPaths>
#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);
}
#ifndef DATABASE_H_
#define DATABASE_H_
#include <string>
// =============================================================================
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_
#include <bctoolbox/logging.h>
#include <bctoolbox/port.h>
#include <linphone/linphonecore.h>
#include <QDateTime>
#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();
const char *context_file = "cpp";
int context_line = 0;
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()
);
QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit();
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 (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);
}
......@@ -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_
#include <QDir>
#include <QFile>
#include <QStandardPaths>
#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);
}
#ifndef PATHS_H_
#define PATHS_H_
#include <string>
// =============================================================================
namespace Paths {
std::string getAvatarsDirpath ();
std::string getCallHistoryFilepath ();
std::string getConfigFilepath ();
std::string getFriendsListFilepath ();
std::string getLogsDirpath ();
std::string getMessageHistoryFilepath ();
}
#endif // PATHS_H_
......@@ -5,7 +5,7 @@
#include <QUuid>
#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)
)
);
......
#include <QTimer>
#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<CoreHandlers>()) {
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());
}
#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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment