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}) ...@@ -46,16 +46,18 @@ foreach (package ${QT5_PACKAGES})
endif () endif ()
endforeach () 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/liblinphone++.so")
list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/libbelcard.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/libbellesip.so")
list(APPEND LIBS "${CMAKE_SOURCE_DIR}/../OUTPUT/desktop/lib64/libbctoolbox.so")
set(SOURCES set(SOURCES
src/app/App.cpp src/app/App.cpp
src/app/AvatarProvider.cpp src/app/AvatarProvider.cpp
src/app/Database.cpp
src/app/DefaultTranslator.cpp src/app/DefaultTranslator.cpp
src/app/Logger.cpp src/app/Logger.cpp
src/app/Paths.cpp
src/components/camera/Camera.cpp src/components/camera/Camera.cpp
src/components/chat/ChatModel.cpp src/components/chat/ChatModel.cpp
src/components/chat/ChatProxyModel.cpp src/components/chat/ChatProxyModel.cpp
...@@ -78,9 +80,9 @@ set(SOURCES ...@@ -78,9 +80,9 @@ set(SOURCES
set(HEADERS set(HEADERS
src/app/App.hpp src/app/App.hpp
src/app/AvatarProvider.hpp src/app/AvatarProvider.hpp
src/app/Database.hpp
src/app/DefaultTranslator.hpp src/app/DefaultTranslator.hpp
src/app/Logger.hpp src/app/Logger.hpp
src/app/Paths.hpp
src/components/camera/Camera.hpp src/components/camera/Camera.hpp
src/components/chat/ChatModel.hpp src/components/chat/ChatModel.hpp
src/components/chat/ChatProxyModel.hpp src/components/chat/ChatProxyModel.hpp
......
#include "Database.hpp" #include "Paths.hpp"
#include "../utils.hpp" #include "../utils.hpp"
#include "AvatarProvider.hpp" #include "AvatarProvider.hpp"
...@@ -12,7 +12,7 @@ AvatarProvider::AvatarProvider () : ...@@ -12,7 +12,7 @@ AvatarProvider::AvatarProvider () :
QQmlImageProviderBase::Image, QQmlImageProviderBase::Image,
QQmlImageProviderBase::ForceAsynchronousImageLoading QQmlImageProviderBase::ForceAsynchronousImageLoading
) { ) {
m_avatars_path = Utils::linphoneStringToQString(Database::getAvatarsPath()); m_avatars_path = Utils::linphoneStringToQString(Paths::getAvatarsDirpath());
} }
QImage AvatarProvider::requestImage ( 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 <QDateTime>
#include "Paths.hpp"
#include "Logger.hpp" #include "Logger.hpp"
#ifdef __linux__ #ifdef __linux__
#define BLUE "\x1B[1;34m" #define BLUE "\x1B[1;34m"
#define YELLOW "\x1B[1;33m"
#define GREEN "\x1B[1;32m" #define GREEN "\x1B[1;32m"
#define PURPLE "\x1B[1;35m" #define PURPLE "\x1B[1;35m"
#define RED "\x1B[1;31m" #define RED "\x1B[1;31m"
#define RESET "\x1B[0m" #define RESET "\x1B[0m"
#else #else
#define BLUE "" #define BLUE ""
#define YELLOW ""
#define GREEN "" #define GREEN ""
#define PURPLE "" #define PURPLE ""
#define RED "" #define RED ""
#define RESET "" #define RESET ""
#endif // ifdef __linux__ #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 local_msg = msg.toLocal8Bit();
QByteArray date_time = QDateTime::currentDateTime() QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit();
.toString("HH:mm:ss").toLocal8Bit();
const char *context_file = "cpp"; fprintf(stderr, format, date_time.constData(), context_str, local_msg.constData());
int context_line = 0; bctbx_log(QT_DOMAIN, level, "QT: %s%s", context_str, local_msg.constData());
if (context.file && !context.function) { if (type == QtFatalMsg)
context_file = context.file; abort();
context_line = context.line; }
}
if (type == QtDebugMsg) // -----------------------------------------------------------------------------
fprintf(
stderr, GREEN "[%s][Debug]" PURPLE "%s:%u: " RESET "%s\n", static void linphoneLogger (const char *domain, OrtpLogLevel type, const char *fmt, va_list args) {
date_time.constData(), context_file, context_line, local_msg.constData() const char *format;
);
else if (type == QtInfoMsg) if (type == ORTP_DEBUG)
fprintf( format = GREEN "[%s][Debug]" YELLOW "Core:%s: " RESET "%s\n";
stderr, BLUE "[%s][Info]" PURPLE "%s:%u: " RESET "%s\n", else if (type == ORTP_TRACE)
date_time.constData(), context_file, context_line, local_msg.constData() format = BLUE "[%s][Trace]" YELLOW "Core:%s: " RESET "%s\n";
); else if (type == ORTP_MESSAGE)
else if (type == QtWarningMsg) format = BLUE "[%s][Info]" YELLOW "Core:%s: " RESET "%s\n";
fprintf( else if (type == ORTP_WARNING)
stderr, RED "[%s][Warning]" PURPLE "%s:%u: " RESET "%s\n", format = RED "[%s][Warning]" YELLOW "Core:%s: " RESET "%s\n";
date_time.constData(), context_file, context_line, local_msg.constData() else if (type == ORTP_ERROR)
); format = RED "[%s][Critical]" YELLOW "Core:%s: " RESET "%s\n";
else if (type == QtCriticalMsg) else if (type == ORTP_FATAL)
fprintf( format = RED "[%s][Fatal]" YELLOW "Core:%s: " RESET "%s\n";
stderr, RED "[%s][Critical]" PURPLE "%s:%u: " RESET "%s\n", else
date_time.constData(), context_file, context_line, local_msg.constData() return;
);
else if (type == QtFatalMsg) { QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit();
fprintf( char *msg = bctbx_strdup_vprintf(fmt, args);
stderr, RED "[%s][Fatal]" PURPLE "%s:%u: " RESET "%s\n",
date_time.constData(), context_file, context_line, local_msg.constData() fprintf(stderr, format, date_time.constData(), domain, msg);
);
bctbx_free(msg);
if (type == ORTP_FATAL)
abort(); 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 @@ ...@@ -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_ #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 @@ ...@@ -5,7 +5,7 @@
#include <QUuid> #include <QUuid>
#include "../../app/App.hpp" #include "../../app/App.hpp"
#include "../../app/Database.hpp" #include "../../app/Paths.hpp"
#include "../../utils.hpp" #include "../../utils.hpp"
#include "../core/CoreManager.hpp" #include "../core/CoreManager.hpp"
...@@ -57,7 +57,7 @@ VcardModel::~VcardModel () { ...@@ -57,7 +57,7 @@ VcardModel::~VcardModel () {
QString image_path( QString image_path(
::Utils::linphoneStringToQString( ::Utils::linphoneStringToQString(
Database::getAvatarsPath() + Paths::getAvatarsDirpath() +
photo->getValue().substr(sizeof(VCARD_SCHEME) - 1) photo->getValue().substr(sizeof(VCARD_SCHEME) - 1)
) )
); );
...@@ -111,7 +111,7 @@ bool VcardModel::setAvatar (const QString &path) { ...@@ -111,7 +111,7 @@ bool VcardModel::setAvatar (const QString &path) {
.arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`. .arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`.
.arg(info.suffix()); .arg(info.suffix());
QString dest = ::Utils::linphoneStringToQString(Database::getAvatarsPath()) + file_id; QString dest = ::Utils::linphoneStringToQString(Paths::getAvatarsDirpath()) + file_id;
if (!file.copy(dest)) if (!file.copy(dest))
return false; return false;
...@@ -127,7 +127,7 @@ bool VcardModel::setAvatar (const QString &path) { ...@@ -127,7 +127,7 @@ bool VcardModel::setAvatar (const QString &path) {
if (old_photo) { if (old_photo) {
QString image_path( QString image_path(
::Utils::linphoneStringToQString( ::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 <QTimer>
#include "../../app/Database.hpp" #include "../../app/Paths.hpp"
#include "CoreManager.hpp" #include "CoreManager.hpp"
...@@ -11,10 +11,7 @@ using namespace std; ...@@ -11,10 +11,7 @@ using namespace std;
CoreManager *CoreManager::m_instance = nullptr; CoreManager *CoreManager::m_instance = nullptr;
CoreManager::CoreManager (QObject *parent) : QObject(parent), m_handlers(make_shared<CoreHandlers>()) { CoreManager::CoreManager (QObject *parent) : QObject(parent), m_handlers(make_shared<CoreHandlers>()) {
string config_path = Database::getConfigPath(); m_core = linphone::Factory::get()->createCore(m_handlers, Paths::getConfigFilepath(), "");
if (config_path.length() == 0)
qFatal("Unable to get config path.");
m_core = linphone::Factory::get()->createCore(m_handlers, config_path, "");
setDatabasesPaths(); setDatabasesPaths();
} }
...@@ -45,20 +42,7 @@ VcardModel *CoreManager::createDetachedVcardModel () { ...@@ -45,20 +42,7 @@ VcardModel *CoreManager::createDetachedVcardModel () {
} }
void CoreManager::setDatabasesPaths () { void CoreManager::setDatabasesPaths () {
string database_path; m_core->setFriendsDatabasePath(Paths::getFriendsListFilepath());
m_core->setCallLogsDatabasePath(Paths::getCallHistoryFilepath());
database_path = Database::getFriendsListPath(); m_core->setChatDatabasePath(Paths::getMessageHistoryFilepath());
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);
} }
#include "app/App.hpp" #include "app/App.hpp"
#include "app/Logger.hpp" #include "app/Logger.hpp"
// =================================================================== // =============================================================================
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
qInstallMessageHandler(logger); Logger::init();
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
App::init(argc, argv); 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