Fix logger files updates, different paths, call history

This commit is contained in:
Julien Wadel 2021-11-17 11:34:42 +01:00
parent 9f781aa434
commit 66c57eca6c
12 changed files with 387 additions and 339 deletions

View file

@ -59,152 +59,152 @@ Logger *Logger::mInstance;
// -----------------------------------------------------------------------------
static inline QByteArray getFormattedCurrentTime () {
return QDateTime::currentDateTime().toString("HH:mm:ss:zzz").toLocal8Bit();
return QDateTime::currentDateTime().toString("HH:mm:ss:zzz").toLocal8Bit();
}
// -----------------------------------------------------------------------------
class LinphoneLogger : public linphone::LoggingServiceListener {
public:
LinphoneLogger (const Logger *logger) : mLogger(logger) {}
LinphoneLogger (const Logger *logger) : mLogger(logger) {}
private:
void onLogMessageWritten (
const shared_ptr<linphone::LoggingService> &,
const string &domain,
linphone::LogLevel level,
const string &message
) override {
if (!mLogger->isVerbose())
return;
using LogLevel = linphone::LogLevel;
const char *format;
switch (level) {
case LogLevel::Debug:
format = GREEN "[%s][Debug]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Trace:
format = BLUE "[%s][Trace]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Message:
format = BLUE "[%s][Info]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Warning:
format = RED "[%s][Warning]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Error:
format = RED "[%s][Error]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Fatal:
format = RED "[%s][Fatal]" YELLOW "Core:%s: " RESET "%s\n";
break;
}
fprintf(
stderr,
format,
getFormattedCurrentTime().constData(),
domain.empty() ? domain.c_str() : EXECUTABLE_NAME,
message.c_str()
);
if (level == LogLevel::Fatal)
terminate();
};
const Logger *mLogger;
void onLogMessageWritten (
const shared_ptr<linphone::LoggingService> &,
const string &domain,
linphone::LogLevel level,
const string &message
) override {
if (!mLogger->isVerbose())
return;
using LogLevel = linphone::LogLevel;
const char *format;
switch (level) {
case LogLevel::Debug:
format = GREEN "[%s][Debug]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Trace:
format = BLUE "[%s][Trace]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Message:
format = BLUE "[%s][Info]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Warning:
format = RED "[%s][Warning]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Error:
format = RED "[%s][Error]" YELLOW "Core:%s: " RESET "%s\n";
break;
case LogLevel::Fatal:
format = RED "[%s][Fatal]" YELLOW "Core:%s: " RESET "%s\n";
break;
}
fprintf(
stderr,
format,
getFormattedCurrentTime().constData(),
domain.empty() ? domain.c_str() : EXECUTABLE_NAME,
message.c_str()
);
if (level == LogLevel::Fatal)
terminate();
};
const Logger *mLogger;
};
// -----------------------------------------------------------------------------
void Logger::log (QtMsgType type, const QMessageLogContext &context, const QString &msg) {
const char *format;
BctbxLogLevel level;
if (type == QtDebugMsg) {
format = GREEN "[%s][%p][Debug]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_DEBUG;
} else if (type == QtInfoMsg) {
format = BLUE "[%s][%p][Info]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_MESSAGE;
} else if (type == QtWarningMsg) {
format = RED "[%s][%p][Warning]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_WARNING;
} else if (type == QtCriticalMsg) {
format = RED "[%s][%p][Critical]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_ERROR;
} else if (type == QtFatalMsg) {
format = RED "[%s][%p][Fatal]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_FATAL;
} else
return;
const char *contextStr = "";
#ifdef QT_MESSAGELOGCONTEXT
QByteArray contextArr;
{
const char *file = context.file;
const char *pos = file ? Utils::rstrstr(file, Constants::SrcPattern) : file;
contextArr = QStringLiteral("%1:%2: ")
.arg(pos ? pos + sizeof(Constants::SrcPattern) - 1 : file)
.arg(context.line)
.toLocal8Bit();
contextStr = contextArr.constData();
}
#else
Q_UNUSED(context);
#endif // ifdef QT_MESSAGELOGCONTEXT
QByteArray localMsg = msg.toLocal8Bit();
QByteArray dateTime = getFormattedCurrentTime();
mMutex.lock();
fprintf(stdout, format, dateTime.constData(), QThread::currentThread(), contextStr, localMsg.constData());
if( level == BCTBX_LOG_FATAL)
QMessageBox::critical(nullptr, "Linphone will crash", msg); // Print an error message before sending msg to bctoolbox
bctbx_log(Constants::QtDomain, level, "QT: %s%s", contextStr, localMsg.constData());
mMutex.unlock();
if (type == QtFatalMsg)
terminate();
const char *format;
BctbxLogLevel level;
if (type == QtDebugMsg) {
format = GREEN "[%s][%p][Debug]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_DEBUG;
} else if (type == QtInfoMsg) {
format = BLUE "[%s][%p][Info]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_MESSAGE;
} else if (type == QtWarningMsg) {
format = RED "[%s][%p][Warning]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_WARNING;
} else if (type == QtCriticalMsg) {
format = RED "[%s][%p][Critical]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_ERROR;
} else if (type == QtFatalMsg) {
format = RED "[%s][%p][Fatal]" PURPLE "%s" RESET "%s\n";
level = BCTBX_LOG_FATAL;
} else
return;
const char *contextStr = "";
#ifdef QT_MESSAGELOGCONTEXT
QByteArray contextArr;
{
const char *file = context.file;
const char *pos = file ? Utils::rstrstr(file, Constants::SrcPattern) : file;
contextArr = QStringLiteral("%1:%2: ")
.arg(pos ? pos + sizeof(Constants::SrcPattern) - 1 : file)
.arg(context.line)
.toLocal8Bit();
contextStr = contextArr.constData();
}
#else
Q_UNUSED(context);
#endif // ifdef QT_MESSAGELOGCONTEXT
QByteArray localMsg = msg.toLocal8Bit();
QByteArray dateTime = getFormattedCurrentTime();
mMutex.lock();
fprintf(stdout, format, dateTime.constData(), QThread::currentThread(), contextStr, localMsg.constData());
if( level == BCTBX_LOG_FATAL)
QMessageBox::critical(nullptr, "Linphone will crash", msg); // Print an error message before sending msg to bctoolbox
bctbx_log(Constants::QtDomain, level, "QT: %s%s", contextStr, localMsg.constData());
mMutex.unlock();
if (type == QtFatalMsg)
terminate();
}
// -----------------------------------------------------------------------------
void Logger::enable (bool status) {
linphone::Core::enableLogCollection(
status
? linphone::LogCollectionState::Enabled
: linphone::LogCollectionState::Disabled
);
linphone::Core::enableLogCollection(
status
? linphone::LogCollectionState::Enabled
: linphone::LogCollectionState::Disabled
);
}
void Logger::init (const shared_ptr<linphone::Config> &config) {
if (mInstance)
return;
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
const QString folder = SettingsModel::getLogsFolder(config);
Q_ASSERT(!folder.isEmpty());
mInstance = new Logger();
qInstallMessageHandler(Logger::log);
{
shared_ptr<linphone::LoggingService> loggingService = mInstance->mLoggingService = linphone::LoggingService::get();
loggingService->setDomain(Constants::QtDomain);
loggingService->setLogLevel(linphone::LogLevel::Message);
loggingService->addListener(make_shared<LinphoneLogger>(mInstance));
}
linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder));
linphone::Core::setLogCollectionPrefix(EXECUTABLE_NAME);
linphone::Core::setLogCollectionMaxFileSize(Constants::MaxLogsCollectionSize);
mInstance->enable(SettingsModel::getLogsEnabled(config));
if (mInstance)
return;
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
const QString folder = SettingsModel::getLogsFolder(config);
Q_ASSERT(!folder.isEmpty());
mInstance = new Logger();
qInstallMessageHandler(Logger::log);
{
shared_ptr<linphone::LoggingService> loggingService = mInstance->mLoggingService = linphone::LoggingService::get();
loggingService->setDomain(Constants::QtDomain);
loggingService->setLogLevel(linphone::LogLevel::Message);
loggingService->addListener(make_shared<LinphoneLogger>(mInstance));
}
linphone::Core::setLogCollectionPrefix(EXECUTABLE_NAME);
linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder));
linphone::Core::setLogCollectionMaxFileSize(Constants::MaxLogsCollectionSize);
mInstance->enable(SettingsModel::getLogsEnabled(config));
}

View file

@ -36,51 +36,51 @@
using namespace std;
static inline bool dirPathExists (const QString &path) {
QDir dir(path);
return dir.exists();
QDir dir(path);
return dir.exists();
}
static inline bool filePathExists (const QString &path, const bool& isWritable) {
QFileInfo info(path);
if (!dirPathExists(info.path()))
return false;
if( isWritable && !info.isWritable())
return false;
QFile file(path);
return file.exists();
QFileInfo info(path);
if (!dirPathExists(info.path()))
return false;
if( isWritable && !info.isWritable())
return false;
QFile file(path);
return file.exists();
}
static inline void ensureDirPathExists (const QString &path) {
QDir dir(path);
if (!dir.exists() && !dir.mkpath(path))
qFatal("Unable to access at directory: `%s`", Utils::appStringToCoreString(path).c_str());
QDir dir(path);
if (!dir.exists() && !dir.mkpath(path))
qFatal("Unable to access at directory: `%s`", Utils::appStringToCoreString(path).c_str());
}
static inline void ensureFilePathExists (const QString &path) {
QFileInfo info(path);
ensureDirPathExists(info.path());
QFile file(path);
if (!file.exists() && !file.open(QIODevice::ReadWrite))
qFatal("Unable to access at path: `%s`", Utils::appStringToCoreString(path).c_str());
QFileInfo info(path);
ensureDirPathExists(info.path());
QFile file(path);
if (!file.exists() && !file.open(QIODevice::ReadWrite))
qFatal("Unable to access at path: `%s`", Utils::appStringToCoreString(path).c_str());
}
static inline string getReadableDirPath (const QString &dirname) {
return Utils::appStringToCoreString(QDir::toNativeSeparators(dirname));
return Utils::appStringToCoreString(QDir::toNativeSeparators(dirname));
}
static inline string getWritableDirPath (const QString &dirname) {
ensureDirPathExists(dirname);
return getReadableDirPath(dirname);
ensureDirPathExists(dirname);
return getReadableDirPath(dirname);
}
static inline string getReadableFilePath (const QString &filename) {
return Utils::appStringToCoreString(QDir::toNativeSeparators(filename));
return Utils::appStringToCoreString(QDir::toNativeSeparators(filename));
}
static inline string getWritableFilePath (const QString &filename) {
ensureFilePathExists(filename);
return getReadableFilePath(filename);
ensureFilePathExists(filename);
return getReadableFilePath(filename);
}
// -----------------------------------------------------------------------------
@ -107,124 +107,128 @@ static inline string getWritableFilePath (const QString &filename) {
// share/
static inline QDir getAppPackageDir () {
QDir dir(QCoreApplication::applicationDirPath());
if (dir.dirName() == QLatin1String("MacOS")) {
dir.cdUp();
} else if( !dir.exists("lib") && !dir.exists("lib64")){// Check if these folders are in the current path
dir.cdUp();
if(!dir.exists("lib") && !dir.exists("lib64") && !dir.exists("plugins"))
QDir dir(QCoreApplication::applicationDirPath());
if (dir.dirName() == QLatin1String("MacOS")) {
dir.cdUp();
} else if( !dir.exists("lib") && !dir.exists("lib64")){// Check if these folders are in the current path
dir.cdUp();
if(!dir.exists("lib") && !dir.exists("lib64") && !dir.exists("plugins"))
qWarning() <<"The application's location is not correct: You have to put your 'bin/' folder next to 'lib/' or 'plugins/' folder.";
}
return dir;
}
return dir;
}
static inline QString getAppPackageDataDirPath() {
QDir dir = getAppPackageDir();
QDir dir = getAppPackageDir();
#ifdef __APPLE__
if (!dir.cd("Resources"))
{
dir.mkdir("Resources");
dir.cd("Resources");
}
if (!dir.cd("Resources"))
{
dir.mkdir("Resources");
dir.cd("Resources");
}
#endif
if (!dir.cd("share"))
{
dir.mkdir("share");
dir.cd("share");
}
return dir.absolutePath();
if (!dir.cd("share"))
{
dir.mkdir("share");
dir.cd("share");
}
return dir.absolutePath();
}
static inline QString getAppPackageMsPluginsDirPath () {
QDir dir = getAppPackageDir();
dir.cd(MSPLUGINS_DIR);
return dir.absolutePath();
QDir dir = getAppPackageDir();
dir.cd(MSPLUGINS_DIR);
return dir.absolutePath();
}
static inline QString getAppPackagePluginsDirPath () {
return getAppPackageDir().absolutePath() + Constants::PathPlugins;
return getAppPackageDir().absolutePath() + Constants::PathPlugins;
}
static inline QString getAppAssistantConfigDirPath () {
return getAppPackageDataDirPath() + Constants::PathAssistantConfig;
return getAppPackageDataDirPath() + Constants::PathAssistantConfig;
}
static inline QString getAppConfigFilePath () {
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + Constants::PathConfig;
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + Constants::PathConfig;
}
static inline QString getAppCallHistoryFilePath () {
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathCallHistoryList;
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathCallHistoryList;
}
static inline QString getAppFactoryConfigFilePath () {
return getAppPackageDataDirPath() + Constants::PathFactoryConfig;
return getAppPackageDataDirPath() + Constants::PathFactoryConfig;
}
static inline QString getAppRootCaFilePath () {
return getAppPackageDataDirPath() + Constants::PathRootCa;
return getAppPackageDataDirPath() + Constants::PathRootCa;
}
static inline QString getAppFriendsFilePath () {
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathFriendsList;
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathFriendsList;
}
static inline QString getAppMessageHistoryFilePath () {
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathMessageHistoryList;
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathMessageHistoryList;
}
static inline QString getAppPluginsDirPath () {
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+ Constants::PathPlugins;
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+ Constants::PathPlugins;
}
// -----------------------------------------------------------------------------
bool Paths::filePathExists (const string &path, const bool isWritable) {
return filePathExists(Utils::coreStringToAppString(path), isWritable);
return filePathExists(Utils::coreStringToAppString(path), isWritable);
}
// -----------------------------------------------------------------------------
string Paths::getAppLocalDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +"/");
}
string Paths::getAssistantConfigDirPath () {
return getReadableDirPath(getAppAssistantConfigDirPath());
return getReadableDirPath(getAppAssistantConfigDirPath());
}
string Paths::getAvatarsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathAvatars);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathAvatars);
}
string Paths::getCallHistoryFilePath () {
return getWritableFilePath(getAppCallHistoryFilePath());
return getWritableFilePath(getAppCallHistoryFilePath());
}
string Paths::getCapturesDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + Constants::PathCaptures);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + Constants::PathCaptures);
}
string Paths::getCodecsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathCodecs);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathCodecs);
}
string Paths::getConfigDirPath (bool writable) {
return writable ? getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)+QDir::separator()) : getReadableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)+QDir::separator());
return writable ? getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)+QDir::separator()) : getReadableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)+QDir::separator());
}
string Paths::getConfigFilePath (const QString &configPath, bool writable) {
QString path;
if( !configPath.isEmpty()){
QFileInfo file(configPath);
if( !writable && (!file.exists() || !file.isFile())){// This file cannot be found. Check if it exists in standard folder
QString defaultConfigPath = Utils::coreStringToAppString(getConfigDirPath(false));
file = QFileInfo(defaultConfigPath+QDir::separator()+configPath);
if( !file.exists() || !file.isFile())
path = "";
else
path = file.absoluteFilePath();
}else
path = file.absoluteFilePath();
}else
path = getAppConfigFilePath();
return writable ? getWritableFilePath(path) : getReadableFilePath(path);
QString path;
if( !configPath.isEmpty()){
QFileInfo file(configPath);
if( !writable && (!file.exists() || !file.isFile())){// This file cannot be found. Check if it exists in standard folder
QString defaultConfigPath = Utils::coreStringToAppString(getConfigDirPath(false));
file = QFileInfo(defaultConfigPath+QDir::separator()+configPath);
if( !file.exists() || !file.isFile())
path = "";
else
path = file.absoluteFilePath();
}else
path = file.absoluteFilePath();
}else
path = getAppConfigFilePath();
return writable ? getWritableFilePath(path) : getReadableFilePath(path);
}
std::string Paths::getDatabaseFilePath (){
@ -232,15 +236,15 @@ std::string Paths::getDatabaseFilePath (){
}
string Paths::getFactoryConfigFilePath () {
return getReadableFilePath(getAppFactoryConfigFilePath());
return getReadableFilePath(getAppFactoryConfigFilePath());
}
string Paths::getFriendsListFilePath () {
return getWritableFilePath(getAppFriendsFilePath());
return getWritableFilePath(getAppFriendsFilePath());
}
string Paths::getDownloadDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
}
std::string Paths::getLimeDatabasePath (){
@ -248,31 +252,35 @@ std::string Paths::getLimeDatabasePath (){
}
string Paths::getLogsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathLogs);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathLogs);
}
string Paths::getMessageHistoryFilePath () {
return getReadableFilePath(getAppMessageHistoryFilePath());// No need to ensure that the file exists as this DB is deprecated
return getReadableFilePath(getAppMessageHistoryFilePath());// No need to ensure that the file exists as this DB is deprecated
}
string Paths::getPackageDataDirPath () {
return getReadableDirPath(getAppPackageDataDirPath());
return getReadableDirPath(getAppPackageDataDirPath() + Constants::PathData);
}
string Paths::getPackageMsPluginsDirPath () {
return getReadableDirPath(getAppPackageMsPluginsDirPath());
return getReadableDirPath(getAppPackageMsPluginsDirPath());
}
string Paths::getPackagePluginsAppDirPath () {
return getReadableDirPath(getAppPackagePluginsDirPath() + Constants::PathPluginsApp);
return getReadableDirPath(getAppPackagePluginsDirPath() + Constants::PathPluginsApp);
}
std::string Paths::getPackageSoundsResourcesDirPath (){
return getReadableDirPath(getAppPackageDataDirPath() + Constants::PathSounds);
}
std::string Paths::getPackageTopDirPath (){
return getReadableDirPath(getAppPackageDataDirPath());
}
string Paths::getPluginsAppDirPath () {
return getWritableDirPath(getAppPluginsDirPath() + Constants::PathPluginsApp);
return getWritableDirPath(getAppPluginsDirPath() + Constants::PathPluginsApp);
}
QStringList Paths::getPluginsAppFolders() {
@ -283,95 +291,97 @@ QStringList Paths::getPluginsAppFolders() {
}
string Paths::getRootCaFilePath () {
return getReadableFilePath(getAppRootCaFilePath());
return getReadableFilePath(getAppRootCaFilePath());
}
string Paths::getThumbnailsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathThumbnails);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathThumbnails);
}
string Paths::getToolsDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathTools);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathTools);
}
string Paths::getUserCertificatesDirPath () {
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathUserCertificates);
return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathUserCertificates);
}
string Paths::getZrtpSecretsFilePath () {
return getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathZrtpSecrets);
return getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + Constants::PathZrtpSecrets);
}
// -----------------------------------------------------------------------------
static void migrateFile (const QString &oldPath, const QString &newPath) {
QFileInfo info(newPath);
ensureDirPathExists(info.path());
if (QFile::copy(oldPath, newPath)) {
QFile::remove(oldPath);
qInfo() << "Migrated" << oldPath << "to" << newPath;
} else {
qWarning() << "Failed migration of" << oldPath << "to" << newPath;
}
QFileInfo info(newPath);
ensureDirPathExists(info.path());
if (QFile::copy(oldPath, newPath)) {
QFile::remove(oldPath);
qInfo() << "Migrated" << oldPath << "to" << newPath;
} else {
qWarning() << "Failed migration of" << oldPath << "to" << newPath;
}
}
static void migrateConfigurationFile (const QString &oldPath, const QString &newPath) {
QFileInfo info(newPath);
ensureDirPathExists(info.path());
if (QFile::copy(oldPath, newPath)) {
QFile oldFile(oldPath);
if (oldFile.open(QIODevice::WriteOnly)) {
QTextStream stream(&oldFile);
stream << "This file has been migrated to " << newPath;
}
QFile::setPermissions(oldPath, QFileDevice::ReadOwner);
qInfo() << "Migrated" << oldPath << "to" << newPath;
} else {
qWarning() << "Failed migration of" << oldPath << "to" << newPath;
}
QFileInfo info(newPath);
ensureDirPathExists(info.path());
if (QFile::copy(oldPath, newPath)) {
QFile oldFile(oldPath);
if (oldFile.open(QIODevice::WriteOnly)) {
QTextStream stream(&oldFile);
stream << "This file has been migrated to " << newPath;
}
QFile::setPermissions(oldPath, QFileDevice::ReadOwner);
qInfo() << "Migrated" << oldPath << "to" << newPath;
} else {
qWarning() << "Failed migration of" << oldPath << "to" << newPath;
}
}
void migrateFlatpakVersionFiles(){
#ifdef Q_OS_LINUX
if(!filePathExists(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/linphone.db", true)){
// Copy all files if linphone.db doesn't exist
QString flatpakPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.var/app/com.belledonnecommunications.linphone/data/linphone";
if( QDir().exists(flatpakPath)){
qInfo() << "Migrating data from Flatpak.";
Utils::copyDir(flatpakPath, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
}
}
if(!filePathExists(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) +Constants::PathDatabase, true)){
// Copy all files if linphone.db doesn't exist
QString flatpakPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.var/app/" APPLICATION_ID "/data/" EXECUTABLE_NAME;
if( QDir().exists(flatpakPath)){
qInfo() << "Migrating data from Flatpak.";
Utils::copyDir(flatpakPath, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
}
}
#endif
}
void migrateGTKVersionFiles(){
QString newPath = getAppConfigFilePath();
QString oldBaseDir = QSysInfo::productType() == QLatin1String("windows")
? QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
: QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
QString oldPath = oldBaseDir + "/.linphonerc";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateConfigurationFile(oldPath, newPath);
newPath = getAppCallHistoryFilePath();
oldPath = oldBaseDir + "/.linphone-call-history.db";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateFile(oldPath, newPath);
newPath = getAppFriendsFilePath();
oldPath = oldBaseDir + "/.linphone-friends.db";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateFile(oldPath, newPath);
newPath = getAppMessageHistoryFilePath();
oldPath = oldBaseDir + "/.linphone-history.db";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateFile(oldPath, newPath);
if( EXECUTABLE_NAME == "linphone"){
QString newPath = getAppConfigFilePath();
QString oldBaseDir = QSysInfo::productType() == QLatin1String("windows")
? QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
: QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
QString oldPath = oldBaseDir + "/.linphonerc";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateConfigurationFile(oldPath, newPath);
newPath = getAppCallHistoryFilePath();
oldPath = oldBaseDir + "/.linphone-call-history.db";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateFile(oldPath, newPath);
newPath = getAppFriendsFilePath();
oldPath = oldBaseDir + "/.linphone-friends.db";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateFile(oldPath, newPath);
newPath = getAppMessageHistoryFilePath();
oldPath = oldBaseDir + "/.linphone-history.db";
if (!filePathExists(newPath, false) && filePathExists(oldPath, false))
migrateFile(oldPath, newPath);
}
}
void Paths::migrate () {
migrateFlatpakVersionFiles(); // First, check Flatpak version as it is the earlier version
migrateGTKVersionFiles();// Then check old version for migration
migrateFlatpakVersionFiles(); // First, check Flatpak version as it is the earlier version
migrateGTKVersionFiles();// Then check old version for migration
}

View file

@ -26,37 +26,38 @@
// =============================================================================
namespace Paths {
bool filePathExists (const std::string &path, const bool isWritable = false);
std::string getAssistantConfigDirPath ();
std::string getAvatarsDirPath ();
std::string getCallHistoryFilePath ();
std::string getCapturesDirPath ();
std::string getCodecsDirPath ();
std::string getConfigDirPath (bool writable = true);
std::string getConfigFilePath (const QString &configPath = QString(), bool writable = true);
std::string getDatabaseFilePath ();
std::string getDownloadDirPath ();
std::string getFactoryConfigFilePath ();
std::string getFriendsListFilePath ();
std::string getLimeDatabasePath ();
std::string getLogsDirPath ();
std::string getMessageHistoryFilePath ();
std::string getPackageDataDirPath ();
std::string getPackageMsPluginsDirPath ();
std::string getPackagePluginsAppDirPath ();
std::string getPackageSoundsResourcesDirPath ();
std::string getPluginsAppDirPath ();
QStringList getPluginsAppFolders();
std::string getRootCaFilePath ();
std::string getThumbnailsDirPath ();
std::string getToolsDirPath ();
std::string getUserCertificatesDirPath ();
std::string getZrtpDataFilePath ();
std::string getZrtpSecretsFilePath ();
void migrate ();
bool filePathExists (const std::string &path, const bool isWritable = false);
std::string getAppLocalDirPath ();
std::string getAssistantConfigDirPath ();
std::string getAvatarsDirPath ();
std::string getCallHistoryFilePath ();
std::string getCapturesDirPath ();
std::string getCodecsDirPath ();
std::string getConfigDirPath (bool writable = true);
std::string getConfigFilePath (const QString &configPath = QString(), bool writable = true);
std::string getDatabaseFilePath ();
std::string getDownloadDirPath ();
std::string getFactoryConfigFilePath ();
std::string getFriendsListFilePath ();
std::string getLimeDatabasePath ();
std::string getLogsDirPath ();
std::string getMessageHistoryFilePath ();
std::string getPackageDataDirPath ();
std::string getPackageMsPluginsDirPath ();
std::string getPackagePluginsAppDirPath ();
std::string getPackageSoundsResourcesDirPath ();
std::string getPackageTopDirPath ();
std::string getPluginsAppDirPath ();
QStringList getPluginsAppFolders();
std::string getRootCaFilePath ();
std::string getThumbnailsDirPath ();
std::string getToolsDirPath ();
std::string getUserCertificatesDirPath ();
std::string getZrtpDataFilePath ();
std::string getZrtpSecretsFilePath ();
void migrate ();
}
#endif // PATHS_H_

View file

@ -401,6 +401,12 @@ void CallsListModel::terminateCall (const QString& sipAddress) const{
}
}
std::list<std::shared_ptr<linphone::CallLog>> CallsListModel::getCallHistory(const QString& peerAddress, const QString& localAddress){
std::shared_ptr<linphone::Address> cleanedPeerAddress = Utils::interpretUrl(Utils::cleanSipAddress(peerAddress));
std::shared_ptr<linphone::Address> cleanedLocalAddress = Utils::interpretUrl(Utils::cleanSipAddress(localAddress));
return CoreManager::getInstance()->getCore()->getCallHistory(cleanedPeerAddress, cleanedLocalAddress);
}
// -----------------------------------------------------------------------------
static void joinConference (const shared_ptr<linphone::Call> &call) {

View file

@ -62,6 +62,8 @@ public:
Q_INVOKABLE void terminateAllCalls () const;
Q_INVOKABLE void terminateCall (const QString& sipAddress) const;
static std::list<std::shared_ptr<linphone::CallLog>> getCallHistory(const QString& peerAddress, const QString& localAddress);
signals:
void callRunning (int index, CallModel *callModel);

View file

@ -37,6 +37,7 @@
#include "app/App.hpp"
#include "app/paths/Paths.hpp"
#include "app/providers/ThumbnailProvider.hpp"
#include "components/calls/CallsListModel.hpp"
#include "components/chat-events/ChatCallModel.hpp"
#include "components/chat-events/ChatEvent.hpp"
#include "components/chat-events/ChatMessageModel.hpp"
@ -194,19 +195,7 @@ ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObj
mChatRoom = chatRoom;
mChatRoomModelListener = std::make_shared<ChatRoomModelListener>(this, parent);
mChatRoom->addListener(mChatRoomModelListener);
// Get Max updatetime from chat room and last call event
auto callHistory = CoreManager::getInstance()->getCore()->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress());
if(callHistory.size() > 0){
auto callDate = callHistory.front()->getStartDate();
if( callHistory.front()->getStatus() == linphone::Call::Status::Success )
callDate += callHistory.front()->getDuration();
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(max(mChatRoom->getLastUpdateTime(), callDate )*1000));
}else
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(mChatRoom->getLastUpdateTime()*1000));
mChatRoom->addListener(mChatRoomModelListener);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
setMissedCallsCount(0);
@ -246,6 +235,15 @@ ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, QObj
}
}else
mParticipantListModel = nullptr;
// Get Max updatetime from chat room and last call event
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
if(callHistory.size() > 0){
auto callDate = callHistory.front()->getStartDate();
if( callHistory.front()->getStatus() == linphone::Call::Status::Success )
callDate += callHistory.front()->getDuration();
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(max(mChatRoom->getLastUpdateTime(), callDate )*1000));
}else
setLastUpdateTime(QDateTime::fromMSecsSinceEpoch(mChatRoom->getLastUpdateTime()*1000));
}
ChatRoomModel::~ChatRoomModel () {
@ -342,7 +340,7 @@ void ChatRoomModel::removeAllEntries () {
if( isOneToOne() && // Remove calls only if chat room is one-one and not secure (if available)
( !standardChatEnabled || !isSecure())
) {
auto callLogs = core->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress());
auto callLogs = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
for(auto callLog : callLogs)
core->removeCallLog(callLog);
}
@ -531,6 +529,18 @@ QList<QString> ChatRoomModel::getComposers(){
return mComposers.values();
}
QString ChatRoomModel::getParticipantAddress(){
if(!isSecure())
return Utils::coreStringToAppString(mChatRoom->getPeerAddress()->asString());
else{
auto participants = getParticipants();
if(participants->getCount() > 1)
return participants->getAt(1)->getSipAddress();
else
return "";
}
}
//------------------------------------------------------------------------------------------------
void ChatRoomModel::setSubject(QString& subject){
@ -819,8 +829,12 @@ void ChatRoomModel::initEntries(){
for(auto &eventLog : mChatRoom->getHistoryEvents(mLastEntriesStep))
prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog);
// Get calls.
if(!isSecure() ) {
auto callHistory = CoreManager::getInstance()->getCore()->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress());
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
if( isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|| standardChatEnabled && !isSecure()) ) {
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
// callhistory is sorted from newest to oldest
int count = 0;
for (auto callLog = callHistory.begin() ; count < mLastEntriesStep && callLog != callHistory.end() ; ++callLog, ++count ){
@ -867,8 +881,12 @@ int ChatRoomModel::loadMoreEntries(){
}
// Calls
if(!isSecure() ) {
auto callHistory = CoreManager::getInstance()->getCore()->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress());
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
if( isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|| standardChatEnabled && !isSecure()) ) {
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
int count = 0;
auto itCallHistory = callHistory.begin();
while(count < entriesCounts[1] && itCallHistory != callHistory.end()){

View file

@ -197,6 +197,7 @@ public:
ParticipantListModel* getParticipants() const;
std::shared_ptr<linphone::ChatRoom> getChatRoom();
QList<QString> getComposers();
QString getParticipantAddress(); // return peerAddress if not secure else return the first participant SIP address.
//---- Setters
void setSubject(QString& subject);

View file

@ -218,19 +218,26 @@ void CoreManager::setDatabasesPaths () {
// -----------------------------------------------------------------------------
void CoreManager::setOtherPaths () {
mCore->setZrtpSecretsFile(Paths::getZrtpSecretsFilePath());
if (mCore->getZrtpSecretsFile().empty() || !Paths::filePathExists(mCore->getZrtpSecretsFile(), true))
mCore->setZrtpSecretsFile(Paths::getZrtpSecretsFilePath());// Use application path if Linphone default is not available
qInfo() << "Using ZrtpSecrets path : " << QString::fromStdString(mCore->getZrtpSecretsFile());
mCore->setUserCertificatesPath(Paths::getUserCertificatesDirPath());
if (mCore->getUserCertificatesPath().empty() || !Paths::filePathExists(mCore->getUserCertificatesPath(), true))
mCore->setUserCertificatesPath(Paths::getUserCertificatesDirPath());// Use application path if Linphone default is not available
qInfo() << "Using UserCertificate path : " << QString::fromStdString(mCore->getUserCertificatesPath());
mCore->setRootCa(Paths::getRootCaFilePath());
if (mCore->getRootCa().empty() || !Paths::filePathExists(mCore->getRootCa()))
mCore->setRootCa(Paths::getRootCaFilePath());// Use application path if Linphone default is not available
qInfo() << "Using RootCa path : " << QString::fromStdString(mCore->getRootCa());
}
void CoreManager::setResourcesPaths () {
shared_ptr<linphone::Factory> factory = linphone::Factory::get();
factory->setMspluginsDir(Paths::getPackageMsPluginsDirPath());
factory->setTopResourcesDir(Paths::getPackageDataDirPath());
factory->setTopResourcesDir(Paths::getPackageTopDirPath());
factory->setSoundResourcesDir(Paths::getPackageSoundsResourcesDirPath());
factory->setDataResourcesDir(Paths::getPackageDataDirPath());
factory->setDataDir(Paths::getAppLocalDirPath());
factory->setDownloadDir(Paths::getDownloadDirPath());
factory->setConfigDir(Paths::getConfigDirPath(true));
}
// -----------------------------------------------------------------------------
@ -271,10 +278,6 @@ void CoreManager::createLinphoneCore (const QString &configPath) {
config->setInt("video", "capture", 1);
config->setInt("video", "display", 1);
}
if(!config->hasEntry("storage", "uri"))
config->setString("storage", "uri", Paths::getDatabaseFilePath());
if(!config->hasEntry("lime", "x3dh_db_path"))
config->setString("lime", "x3dh_db_path", Paths::getLimeDatabasePath());
mCore->start();
setDatabasesPaths();
setOtherPaths();

View file

@ -21,6 +21,7 @@
#include "components/core/CoreManager.hpp"
#include "components/participant/ParticipantListModel.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "utils/Utils.hpp"
@ -94,6 +95,10 @@ bool TimelineProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sou
bool haveEncryption = timeline->getChatRoomModel()->haveEncryption();
bool isEphemeral = timeline->getChatRoomModel()->isEphemeralEnabled();
if(!CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled() && !haveEncryption)
return false;
if(!CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled() && haveEncryption)
return false;
if( mFilterFlags > 0) {
if( !show && ( (mFilterFlags & TimelineFilter::SimpleChatRoom) == TimelineFilter::SimpleChatRoom))

View file

@ -32,6 +32,7 @@ constexpr char Constants::PathAssistantConfig[];
constexpr char Constants::PathAvatars[];
constexpr char Constants::PathCaptures[];
constexpr char Constants::PathCodecs[];
constexpr char Constants::PathData[];
constexpr char Constants::PathTools[];
constexpr char Constants::PathLogs[];
#ifdef APPLE

View file

@ -78,6 +78,7 @@ public:
static constexpr char PathAvatars[] = "/avatars/";
static constexpr char PathCaptures[] = "/" EXECUTABLE_NAME "/captures/";
static constexpr char PathCodecs[] = "/codecs/";
static constexpr char PathData[] = "/" EXECUTABLE_NAME;
static constexpr char PathTools[] = "/tools/";
static constexpr char PathLogs[] = "/logs/";
#ifdef APPLE
@ -92,7 +93,7 @@ public:
static constexpr char PathCallHistoryList[] = "/call-history.db";
static constexpr char PathConfig[] = "/linphonerc";
static constexpr char PathDatabase[] = "/" EXECUTABLE_NAME ".db";
static constexpr char PathDatabase[] = "/linphone.db";
static constexpr char PathFactoryConfig[] = "/" EXECUTABLE_NAME "/linphonerc-factory";
static constexpr char PathRootCa[] = "/" EXECUTABLE_NAME "/rootca.pem";
static constexpr char PathFriendsList[] = "/friends.db";

@ -1 +1 @@
Subproject commit b1171bf5faf08237ddc6e074b71dd6319c0470af
Subproject commit 81e6b6b4a93317d14b0ecf89a3e0f82991d43707