File indexing completed on 2024-11-10 04:30:22
0001 /* 0002 * SPDX-FileCopyrightText: 2012-2016 Ivan Cukic <ivan.cukic@kde.org> 0003 * SPDX-FileCopyrightText: 2022 Alex Kuznetsov <alex@vxpro.io> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include "KioActivitiesApi.h" 0009 #include "KioActivities.h" 0010 0011 #include <QCoreApplication> 0012 0013 #include <QByteArray> 0014 #include <QDebug> 0015 #include <QDir> 0016 #include <QFile> 0017 #include <QSqlDatabase> 0018 #include <QSqlDriver> 0019 #include <QSqlError> 0020 #include <QSqlField> 0021 #include <QSqlQuery> 0022 #include <QStandardPaths> 0023 #include <QUrl> 0024 0025 #include <KIO/StatJob> 0026 #include <KLocalizedString> 0027 #include <KUser> 0028 0029 #include <common/database/Database.h> 0030 #include <utils/d_ptr_implementation.h> 0031 #include <utils/qsqlquery_iterator.h> 0032 0033 #include <PlasmaActivities/Consumer> 0034 #include <PlasmaActivities/Info> 0035 0036 #include <QProcess> 0037 0038 ActivitiesProtocolApi::ActivitiesProtocolApi() 0039 { 0040 } 0041 0042 ActivitiesProtocolApi::PathType ActivitiesProtocolApi::pathType(const QUrl &url, QString *activity, QString *filePath) const 0043 { 0044 const auto fullPath = url.adjusted(QUrl::StripTrailingSlash).path(); 0045 const auto path = QStringView(fullPath).mid(fullPath.startsWith(QLatin1Char('/')) ? 1 : 0); 0046 0047 if (activity && !path.isEmpty()) { 0048 *activity = path.mid(0, path.indexOf(QStringLiteral("/"))).toString(); 0049 } 0050 0051 if (filePath) { 0052 auto strippedPath = path.mid(path.indexOf(QStringLiteral("/")) + 1); 0053 auto splitPosition = strippedPath.indexOf(QStringLiteral("/")); 0054 0055 if (splitPosition == -1) { 0056 // if we have only one path segment 0057 *filePath = demangledPath(strippedPath.toString()); 0058 0059 } else { 0060 // if we have sub-paths 0061 auto head = strippedPath.mid(0, splitPosition); 0062 auto tail = strippedPath.mid(splitPosition); 0063 0064 *filePath = demangledPath(head.toString()) + tail.toString(); 0065 } 0066 } 0067 0068 return path.length() == 0 ? RootItem : path.contains(QStringLiteral("/")) ? ActivityPathItem : ActivityRootItem; 0069 } 0070 0071 void ActivitiesProtocolApi::syncActivities(KActivities::Consumer &activities) 0072 { 0073 // We need to use the consumer in a synchronized way 0074 while (activities.serviceStatus() == KActivities::Consumer::Unknown) { 0075 QCoreApplication::processEvents(); 0076 } 0077 } 0078 0079 KIO::UDSEntry ActivitiesProtocolApi::activityEntry(const QString &activity) 0080 { 0081 KIO::UDSEntry uds; 0082 uds.reserve(8); 0083 KActivities::Info activityInfo(activity); 0084 uds.fastInsert(KIO::UDSEntry::UDS_NAME, activity); 0085 uds.fastInsert(KIO::UDSEntry::UDS_DISPLAY_NAME, activityInfo.name()); 0086 uds.fastInsert(KIO::UDSEntry::UDS_DISPLAY_TYPE, i18n("Activity")); 0087 uds.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, activityInfo.icon()); 0088 uds.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); 0089 uds.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); 0090 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS, 0500); 0091 uds.fastInsert(KIO::UDSEntry::UDS_USER, KUser().loginName()); 0092 return uds; 0093 } 0094 0095 KIO::UDSEntry ActivitiesProtocolApi::filesystemEntry(const QString &path) 0096 { 0097 KIO::UDSEntry uds; 0098 auto url = QUrl::fromLocalFile(path); 0099 0100 if (KIO::StatJob *job = KIO::stat(url, KIO::HideProgressInfo)) { 0101 QScopedPointer<KIO::StatJob> sp(job); 0102 job->setAutoDelete(false); 0103 if (job->exec()) { 0104 uds = job->statResult(); 0105 } 0106 } 0107 0108 auto mangled = mangledPath(path); 0109 // QProcess::execute("kdialog", { "--passivepopup", mangled }); 0110 0111 uds.replace(KIO::UDSEntry::UDS_NAME, mangled); 0112 uds.replace(KIO::UDSEntry::UDS_DISPLAY_NAME, url.fileName()); 0113 uds.replace(KIO::UDSEntry::UDS_TARGET_URL, url.url()); 0114 uds.replace(KIO::UDSEntry::UDS_LOCAL_PATH, path); 0115 0116 return uds; 0117 } 0118 0119 QString ActivitiesProtocolApi::mangledPath(const QString &path) const 0120 { 0121 // return QString::fromUtf8(QUrl::toPercentEncoding(path)); 0122 return QString::fromLatin1(path.toUtf8().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); 0123 } 0124 0125 QString ActivitiesProtocolApi::demangledPath(const QString &mangled) const 0126 { 0127 // return QUrl::fromPercentEncoding(mangled.toUtf8()); 0128 return QString::fromUtf8(QByteArray::fromBase64(mangled.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); 0129 }