File indexing completed on 2024-05-12 05:46:33
0001 /* 0002 Copyright (C) 2008-2010 by Sebastian Trueg <trueg at kde.org> 0003 Copyright (C) 2012-2014 by Vishesh Handa <me@vhanda.in> 0004 0005 This program is free software; you can redistribute it and/or modify 0006 it under the terms of the GNU General Public License as published by 0007 the Free Software Foundation; either version 2, or (at your option) 0008 any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kio_search.h" 0021 0022 #include "query.h" 0023 #include "resultiterator.h" 0024 #include "idutils.h" 0025 0026 #include <QUrl> 0027 #include <QUrlQuery> 0028 #include <KUser> 0029 #include <QCoreApplication> 0030 #include <KLocalizedString> 0031 0032 #include <KIO/Job> 0033 0034 using namespace Baloo; 0035 0036 namespace 0037 { 0038 0039 KIO::UDSEntry statSearchFolder(const QUrl& url) 0040 { 0041 KIO::UDSEntry uds; 0042 uds.reserve(9); 0043 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS, 0700); 0044 uds.fastInsert(KIO::UDSEntry::UDS_USER, KUser().loginName()); 0045 uds.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); 0046 uds.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); 0047 uds.fastInsert(KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES, QStringLiteral("baloo")); 0048 uds.fastInsert(KIO::UDSEntry::UDS_DISPLAY_TYPE, i18n("Search Folder")); 0049 uds.fastInsert(KIO::UDSEntry::UDS_URL, url.url()); 0050 0051 QUrlQuery query(url); 0052 QString title = query.queryItemValue(QStringLiteral("title"), QUrl::FullyDecoded); 0053 if (!title.isEmpty()) { 0054 uds.fastInsert(KIO::UDSEntry::UDS_NAME, title); 0055 uds.fastInsert(KIO::UDSEntry::UDS_DISPLAY_NAME, title); 0056 } 0057 0058 return uds; 0059 } 0060 0061 } 0062 0063 SearchProtocol::SearchProtocol(const QByteArray& poolSocket, const QByteArray& appSocket) 0064 : KIO::SlaveBase("baloosearch", poolSocket, appSocket) 0065 { 0066 } 0067 0068 0069 SearchProtocol::~SearchProtocol() 0070 { 0071 } 0072 0073 static QString jsonQueryForType(const QString &type) 0074 { 0075 const QString jsonQuery(QStringLiteral("{\"dayFilter\": 0,\ 0076 \"monthFilter\": 0, \ 0077 \"yearFilter\": 0, \ 0078 \"type\": [ \"%1\"]}")); 0079 return jsonQuery.arg(type); 0080 } 0081 0082 static QString jsonQueryFromUrl(const QUrl &url) 0083 { 0084 const QString path = url.path(); 0085 0086 if (path == QLatin1String("/documents")) { 0087 return jsonQueryForType(QStringLiteral("Document")); 0088 } else if (path.endsWith(QLatin1String("/images"))) { 0089 return jsonQueryForType(QStringLiteral("Image")); 0090 } else if (path.endsWith(QLatin1String("/audio"))) { 0091 return jsonQueryForType(QStringLiteral("Audio")); 0092 } else if (path.endsWith(QLatin1String("/videos"))) { 0093 return jsonQueryForType(QStringLiteral("Video")); 0094 } 0095 0096 return QString(); 0097 } 0098 0099 void SearchProtocol::listDir(const QUrl& url) 0100 { 0101 Query q; 0102 0103 QUrlQuery urlQuery(url); 0104 if (urlQuery.hasQueryItem(QStringLiteral("json"))) { 0105 QString jsonString = urlQuery.queryItemValue(QStringLiteral("json"), QUrl::FullyDecoded); 0106 q = Query::fromJSON(jsonString.toUtf8()); 0107 } else if (urlQuery.hasQueryItem(QStringLiteral("query"))) { 0108 QString queryString = urlQuery.queryItemValue(QStringLiteral("query"), QUrl::FullyDecoded); 0109 0110 q.setSearchString(queryString); 0111 } else { 0112 const QString jsonString = jsonQueryFromUrl(url); 0113 if (!jsonString.isEmpty()) { 0114 q = Query::fromJSON(jsonString.toUtf8()); 0115 } 0116 } 0117 0118 q.setSortingOption(Query::SortNone); 0119 ResultIterator it = q.exec(); 0120 0121 while (it.next()) { 0122 KIO::UDSEntry uds; 0123 uds.reserve(10); 0124 const QString filePath(it.filePath()); 0125 0126 // Code from kdelibs/kioslaves/file.cpp 0127 QT_STATBUF statBuf; 0128 const QByteArray ba = QFile::encodeName(filePath); 0129 if (filePathToStat(ba, statBuf) == 0) { 0130 uds.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, statBuf.st_mtime); 0131 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, statBuf.st_atime); 0132 uds.fastInsert(KIO::UDSEntry::UDS_SIZE, statBuf.st_size); 0133 #ifndef Q_OS_WIN 0134 uds.fastInsert(KIO::UDSEntry::UDS_USER, getUserName(KUserId(statBuf.st_uid))); 0135 uds.fastInsert(KIO::UDSEntry::UDS_GROUP, getGroupName(KGroupId(statBuf.st_gid))); 0136 #else 0137 #pragma message("TODO: st_uid and st_gid are always zero, use GetSecurityInfo to find the owner") 0138 #endif 0139 0140 mode_t type = statBuf.st_mode & S_IFMT; 0141 mode_t access = statBuf.st_mode & 07777; 0142 0143 uds.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, type); 0144 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS, access); 0145 } 0146 else { 0147 continue; 0148 } 0149 0150 QUrl url = QUrl::fromLocalFile(filePath); 0151 uds.fastInsert(KIO::UDSEntry::UDS_NAME, url.fileName()); 0152 uds.fastInsert(KIO::UDSEntry::UDS_URL, url.url()); 0153 uds.fastInsert(KIO::UDSEntry::UDS_LOCAL_PATH, filePath); 0154 0155 listEntry(uds); 0156 } 0157 0158 KIO::UDSEntry uds; 0159 uds.reserve(5); 0160 uds.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); 0161 uds.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); 0162 uds.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory")); 0163 uds.fastInsert(KIO::UDSEntry::UDS_ACCESS, 0700); 0164 uds.fastInsert(KIO::UDSEntry::UDS_USER, KUser().loginName()); 0165 listEntry(uds); 0166 0167 finished(); 0168 } 0169 0170 0171 void SearchProtocol::mimetype(const QUrl&) 0172 { 0173 mimeType(QStringLiteral("inode/directory")); 0174 finished(); 0175 } 0176 0177 0178 void SearchProtocol::stat(const QUrl& url) 0179 { 0180 statEntry(statSearchFolder(url)); 0181 finished(); 0182 } 0183 0184 QString SearchProtocol::getUserName(const KUserId &uid) const 0185 { 0186 if (Q_UNLIKELY(!uid.isValid())) { 0187 return QString(); 0188 } 0189 if (!mUsercache.contains(uid)) { 0190 KUser user(uid); 0191 QString name = user.loginName(); 0192 if (name.isEmpty()) { 0193 name = uid.toString(); 0194 } 0195 mUsercache.insert(uid, name); 0196 return name; 0197 } 0198 return mUsercache[uid]; 0199 } 0200 0201 QString SearchProtocol::getGroupName(const KGroupId &gid) const 0202 { 0203 if (Q_UNLIKELY(!gid.isValid())) { 0204 return QString(); 0205 } 0206 if (!mGroupcache.contains(gid)) { 0207 KUserGroup group(gid); 0208 QString name = group.name(); 0209 if (name.isEmpty()) { 0210 name = gid.toString(); 0211 } 0212 mGroupcache.insert(gid, name); 0213 return name; 0214 } 0215 return mGroupcache[gid]; 0216 } 0217 0218 0219 extern "C" 0220 { 0221 Q_DECL_EXPORT int kdemain(int argc, char** argv) 0222 { 0223 QCoreApplication app(argc, argv); 0224 app.setApplicationName(QStringLiteral("kio_baloosearch")); 0225 Baloo::SearchProtocol slave(argv[2], argv[3]); 0226 slave.dispatchLoop(); 0227 return 0; 0228 } 0229 }