File indexing completed on 2024-04-21 04:49:07
0001 /* 0002 * SPDX-FileCopyrightText: 2020 George Florea Bănuș <georgefb899@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "worker.h" 0008 0009 #include "application.h" 0010 #include "framedecoder.h" 0011 #include "generalsettings.h" 0012 0013 #include <QCryptographicHash> 0014 #include <QDir> 0015 #include <QFileInfo> 0016 #include <QImage> 0017 #include <QQuickWindow> 0018 #include <QThread> 0019 0020 #include <KConfig> 0021 #include <KConfigGroup> 0022 #include <KFileMetaData/ExtractorCollection> 0023 #include <KFileMetaData/SimpleExtractionResult> 0024 #include <KWindowConfig> 0025 0026 Worker *Worker::instance() 0027 { 0028 static Worker w; 0029 return &w; 0030 } 0031 0032 void Worker::getMetaData(int index, const QString &path) 0033 { 0034 auto url = QUrl::fromUserInput(path); 0035 if (url.scheme() != QStringLiteral("file")) { 0036 return; 0037 } 0038 QString mimeType = Application::mimeType(url); 0039 KFileMetaData::ExtractorCollection exCol; 0040 QList<KFileMetaData::Extractor *> extractors = exCol.fetchExtractors(mimeType); 0041 KFileMetaData::SimpleExtractionResult result(path, mimeType, KFileMetaData::ExtractionResult::ExtractMetaData); 0042 if (extractors.size() == 0) { 0043 return; 0044 } 0045 KFileMetaData::Extractor *ex = extractors.first(); 0046 ex->extract(&result); 0047 0048 auto properties = result.properties(); 0049 0050 Q_EMIT metaDataReady(index, properties); 0051 } 0052 0053 void Worker::makePlaylistThumbnail(const QString &path, int width) 0054 { 0055 QImage image; 0056 0057 auto file = QUrl::fromUserInput(path); 0058 0059 // figure out absolute path of the thumbnail 0060 auto md5Hash = QCryptographicHash::hash(file.toString().toUtf8(), QCryptographicHash::Md5); 0061 QString cacheDir(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); 0062 QString appDir(QStringLiteral("haruna")); 0063 QString fileDir(QString::fromUtf8(md5Hash.toHex())); 0064 QString filename(QString::fromUtf8(md5Hash.toHex()).append(QStringLiteral(".png"))); 0065 QString separator(QStringLiteral("/")); 0066 QString cachedFilePath = cacheDir + separator + appDir + separator + fileDir + separator + filename; 0067 0068 // load existing thumbnail if there is one 0069 if (QFileInfo::exists(cachedFilePath) && image.load(cachedFilePath)) { 0070 Q_EMIT thumbnailSuccess(path, image); 0071 return; 0072 } 0073 0074 image = frameToImage(path, width); 0075 0076 if (image.isNull()) { 0077 qDebug() << QStringLiteral("Failed to create thumbnail for file: %1").arg(path); 0078 return; 0079 } 0080 Q_EMIT thumbnailSuccess(path, image); 0081 0082 QFileInfo fi(cachedFilePath); 0083 // create folders where the file will be saved 0084 if (QDir().mkpath(fi.absolutePath())) { 0085 if (!image.save(cachedFilePath)) { 0086 qDebug() << QStringLiteral("Failed to save thumbnail for file: %1").arg(path); 0087 } 0088 } 0089 } 0090 0091 QImage Worker::frameToImage(const QString &path, int width) 0092 { 0093 QImage image; 0094 FrameDecoder frameDecoder(path, nullptr); 0095 if (!frameDecoder.getInitialized()) { 0096 return image; 0097 } 0098 // before seeking, a frame has to be decoded 0099 if (!frameDecoder.decodeVideoFrame()) { 0100 return image; 0101 } 0102 0103 int secondToSeekTo = frameDecoder.getDuration() * 20 / 100; 0104 frameDecoder.seek(secondToSeekTo); 0105 frameDecoder.getScaledVideoFrame(width, true, image); 0106 0107 return image; 0108 } 0109 0110 void Worker::mprisThumbnail(const QString &path, int width) 0111 { 0112 QImage image; 0113 FrameDecoder frameDecoder(path, nullptr); 0114 if (!frameDecoder.getInitialized()) { 0115 return; 0116 } 0117 // before seeking, a frame has to be decoded 0118 if (!frameDecoder.decodeVideoFrame()) { 0119 return; 0120 } 0121 0122 int secondToSeekTo = frameDecoder.getDuration() * 20 / 100; 0123 frameDecoder.seek(secondToSeekTo); 0124 frameDecoder.getScaledVideoFrame(width, true, image); 0125 0126 Q_EMIT mprisThumbnailSuccess(image); 0127 } 0128 0129 void Worker::syncConfigValue(QString path, QString group, QString key, QVariant value) 0130 { 0131 if (!m_cachedConf || m_cachedConf->name() != path) { 0132 m_cachedConf.reset(new KConfig(path)); 0133 } 0134 0135 m_cachedConf->group(group).writeEntry(key, value); 0136 m_cachedConf->sync(); 0137 } 0138 0139 void Worker::saveWindowGeometry(QQuickWindow *window) const 0140 { 0141 if (!GeneralSettings::rememberWindowGeometry()) { 0142 return; 0143 } 0144 KConfig dataResource(QStringLiteral("data"), KConfig::SimpleConfig, QStandardPaths::AppDataLocation); 0145 KConfigGroup windowGroup(&dataResource, QStringLiteral("Window")); 0146 KWindowConfig::saveWindowPosition(window, windowGroup); 0147 KWindowConfig::saveWindowSize(window, windowGroup); 0148 dataResource.sync(); 0149 } 0150 0151 #include "moc_worker.cpp"