diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ writercollection.cpp externalwriter.cpp formatstrings.cpp + mimeutils.cpp ) ecm_qt_declare_logging_category(KF5FileMetaData_SRCS HEADER kfilemetadata_debug.h IDENTIFIER KFILEMETADATA_LOG CATEGORY_NAME kf5.kfilemetadata) diff --git a/src/mimeutils.h b/src/mimeutils.h new file mode 100644 --- /dev/null +++ b/src/mimeutils.h @@ -0,0 +1,55 @@ +/* + * This file is part of KFileMetaData + * Copyright (C) 2019 Stefan Brüns + * + * 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 + * + */ + +#ifndef KFILEMETADATA_MIMEUTILS +#define KFILEMETADATA_MIMEUTILS + +#include +#include "kfilemetadata_export.h" + +namespace KFileMetaData +{ +namespace MimeUtils +{ + +/** + * Returns the mimetype for a file + * + * The function uses both content and filename to determine the + * \c QMimeType. In case the extension mimetype is more specific + * than the content mimetype, and the first inherits the latter, + * the extension mimetype is preferred. + * If the extension does not match the content, the content has + * higher priority. + * The file must exist and be readable. + * + * @since 5.57 + * + * \sa QMimeDatabase::mimeTypesForFileName + * \sa QMimeType::inherits + */ +KFILEMETADATA_EXPORT +QMimeType strictMimeType(const QString& filePath, const QMimeDatabase& db); + + +} // namespace MimeUtils +} // namespace KFileMetaData + +#endif // KFILEMETADATA_MIMEUTILS diff --git a/src/mimeutils.cpp b/src/mimeutils.cpp new file mode 100644 --- /dev/null +++ b/src/mimeutils.cpp @@ -0,0 +1,50 @@ +/* + * This file is part of KFileMetaData + * Copyright (C) 2019 Stefan Brüns + * + * 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 + * + */ + +#include "mimeutils.h" + +namespace KFileMetaData { +namespace MimeUtils { + +QMimeType strictMimeType(const QString& filePath, const QMimeDatabase& db) +{ + auto extensionMimes = db.mimeTypesForFileName(filePath); + auto contentMime = db.mimeTypeForFile(filePath, QMimeDatabase::MatchContent); + + if (extensionMimes.contains(contentMime)) { + // content based mime type is one of the types for the file extension, e.g.: + // *.ogg -> [ audio/ogg, audio/x-vorbis+ogg, ...] + // content -> audio/x-vorbis+ogg + return contentMime; + } + + for (auto mime : extensionMimes) { + // check if the content is generic and the extension is more specific, e.g.: + // *.mkv -> [ video/matroska ] + // content -> application/matroska + if (mime.inherits(contentMime.name())) { + return mime; + } + } + // content mime type does not match the extension, trust the content + return contentMime; +} + +}} // namespace KFileMetaData::MimeUtils