/* BEGIN_COMMON_COPYRIGHT_HEADER * (c)LGPL2+ * * Flacon - audio File Encoder * https://github.com/flacon/flacon * * Copyright: 2023 * Alexander Sokoloff * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * END_COMMON_COPYRIGHT_HEADER */ #include "extprogram.h" #include #include #include #include #include "types.h" #include namespace { Q_LOGGING_CATEGORY(LOG, "ExtProgram") } #ifdef Q_OS_WIN static constexpr auto PATH_ENV_SEPARATOR = ';'; static constexpr auto BINARY_EXT = ".exe"; #elif defined(Q_OS_OS2) static constexpr auto PATH_ENV_SEPARATOR = ';'; static constexpr auto BINARY_EXT = ".exe"; #else #ifndef BUNDLED_PROGRAMS static constexpr auto PATH_ENV_SEPARATOR = ':'; static constexpr auto BINARY_EXT = ""; #endif #endif ExtProgram::ExtProgram(const QString &name) : mName(name) { #ifdef BUNDLED_PROGRAMS mPath = QDir(qApp->applicationDirPath()).absoluteFilePath(name); #endif } void ExtProgram::setPath(const QString &path) { Q_UNUSED(path); #ifndef BUNDLED_PROGRAMS mPath = path; #endif } QString ExtProgram::find() const { #ifdef BUNDLED_PROGRAMS return mPath; #else QStringList paths = QProcessEnvironment::systemEnvironment().value("PATH").split(PATH_ENV_SEPARATOR); foreach (QString path, paths) { QFileInfo fi(path + QDir::separator() + mName + BINARY_EXT); if (fi.exists() && fi.isExecutable()) { return fi.absoluteFilePath(); } } return ""; #endif } bool ExtProgram::check(QStringList *errors) const { if (mPath.isEmpty()) { if (errors) { *errors << QCoreApplication::translate("ExtProgram", "The %1 program is not installed.
Verify that all required programs are installed and in your preferences.", "Error message. %1 - is an program name") .arg(mName); } return false; } QFileInfo fi(mPath); if (!fi.exists()) { if (errors) { *errors << QCoreApplication::translate("ExtProgram", "The %1 program is installed according to your settings, but the binary file can’t be found.
" "Verify that all required programs are installed and in your preferences.", "Error message. %1 - is an program name") .arg(mName); } return false; } if (!fi.isExecutable()) { if (errors) { *errors << QCoreApplication::translate("ExtProgram", "The %1 program is installed according to your settings, but the file is not executable.
" "Verify that all required programs are installed and in your preferences.", "Error message. %1 - is an program name") .arg(mName); } return false; } return true; } QList ExtProgram::allPrograms() { QList res; res << alacenc(); res << faac(); res << flac(); res << lame(); res << mac(); res << oggenc(); res << opusenc(); res << sox(); res << ttaenc(); res << wavpack(); res << wvunpack(); return res; } QProcess *ExtProgram::open(QObject *parent) const { QProcess *proc = new QProcess(parent); proc->setProgram(path()); // QDir::toNativeSeparators(prog); proc->connect(proc, &QProcess::errorOccurred, proc, [proc](QProcess::ProcessError error) { qCWarning(LOG) << "ERROR"; qCWarning(LOG) << QStringLiteral("%1: The '%2' program crashes").arg(proc->objectName()).arg(proc->program()); qCWarning(LOG) << "Program with args:" << debugProgramArgs(proc->program(), proc->arguments()); qCWarning(LOG) << "Error:" << error; qCWarning(LOG) << "Error string:" << proc->errorString(); if (proc->isOpen()) { qCWarning(LOG) << "Stderr: ............"; qCWarning(LOG) << proc->readAllStandardError(); qCWarning(LOG) << "...................."; } QString msg = QStringLiteral("The '%1' program crashes with an error: %2").arg(proc->program()).arg(proc->errorString()); throw FlaconError(msg); }); return proc; } QProcess *ExtProgram::open(const QStringList &args, QObject *parent) const { QProcess *res = open(parent); res->setArguments(args); return res; } // clang-format off ExtProgram *ExtProgram::alacenc() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::faac() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::flac() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::lame() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::mac() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::oggenc() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::opusenc() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::sox() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::ttaenc() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::wavpack() { static ExtProgram res(__FUNCTION__); return &res; } ExtProgram *ExtProgram::wvunpack(){ static ExtProgram res(__FUNCTION__); return &res; } // clang-format on