1 /*
2 SPDX-FileCopyrightText: %{CURRENT_YEAR} %{AUTHOR} <%{EMAIL}>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7 #include "%{APPNAMELC}.h"
8
9 #include "%{APPNAMELC}_log.h"
10 #include "mydatasystem.h"
11 // KF
12 #include <KIO/UDSEntry>
13 #include <KLocalizedString>
14 // Qt
15 #include <QCoreApplication>
16
17 // Pseudo plugin class to embed meta data
18 class KIOPluginForMetaData : public QObject
19 {
20 Q_OBJECT
21 Q_PLUGIN_METADATA(IID "org.kde.kio.slave.myproto" FILE "myproto.json")
22 };
23
24 extern "C" {
25 int Q_DECL_EXPORT kdemain(int argc, char **argv);
26 }
27
kdemain(int argc,char ** argv)28 int kdemain(int argc, char **argv)
29 {
30 QCoreApplication app(argc, argv);
31 app.setApplicationName(QStringLiteral("%{APPNAME}"));
32
33 %{APPNAME} slave(argv[2], argv[3]);
34 slave.dispatchLoop();
35
36 return 0;
37 }
38
39 // utils methods to map our data into KIO data
40 namespace
41 {
42
groupPath(const QUrl & url)43 QStringList groupPath(const QUrl &url)
44 {
45 QString path = url.adjusted(QUrl::StripTrailingSlash).path();
46 if (path.startsWith(QLatin1Char('/'))) {
47 path.remove(0, 1);
48 }
49 return path.isEmpty() ? QStringList() : path.split(QLatin1Char('/'));
50 }
51
fileEntry(const DataItem & item)52 KIO::UDSEntry fileEntry(const DataItem &item)
53 {
54 KIO::UDSEntry entry;
55 entry.reserve(5);
56 entry.fastInsert(KIO::UDSEntry::UDS_NAME, item.name);
57 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("text/plain"));
58 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG);
59 entry.fastInsert(KIO::UDSEntry::UDS_SIZE, item.data().size());
60 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH);
61 return entry;
62 }
63
dirEntry(const QString & name)64 KIO::UDSEntry dirEntry(const QString &name)
65 {
66 KIO::UDSEntry entry;
67
68 entry.reserve(4);
69 entry.fastInsert(KIO::UDSEntry::UDS_NAME, name);
70 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("inode/directory"));
71 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
72 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH);
73
74 return entry;
75 }
76
77 }
78
79 %{APPNAME}::%{APPNAME}(const QByteArray &pool_socket, const QByteArray &app_socket)
80 : KIO::SlaveBase("myproto", pool_socket, app_socket)
81 , m_dataSystem(new MyDataSystem)
82 {
83 qCDebug(%{APPNAMEUC}_LOG) << "%{APPNAME} starting up";
84 }
85
86 %{APPNAME}::~%{APPNAME}()
87 {
88 qCDebug(%{APPNAMEUC}_LOG) << "%{APPNAME} shutting down";
89 }
90
91
get(const QUrl & url)92 void %{APPNAME}::get(const QUrl &url)
93 {
94 qCDebug(%{APPNAMEUC}_LOG) << "%{APPNAME} starting get" << url;
95
96 QStringList groupPath = ::groupPath(url);
97 const QString itemName = groupPath.takeLast();
98 const DataItem item = m_dataSystem->item(groupPath, itemName);
99 if (!item.isValid()) {
100 groupPath.append(itemName);
101 if (m_dataSystem->hasGroup(groupPath)) {
102 error(KIO::ERR_IS_DIRECTORY, itemName);
103 } else {
104 }
105 error(KIO::ERR_DOES_NOT_EXIST, itemName);
106 return;
107 }
108
109 // as first notify about the MIME type, so the handler can be selected
110 mimeType("text/plain");
111
112 // now emit the data...
113 data(item.data());
114
115 // and we are done
116 finished();
117 }
118
stat(const QUrl & url)119 void %{APPNAME}::stat(const QUrl &url)
120 {
121 qCDebug(%{APPNAMEUC}_LOG) << "%{APPNAME} starting stat" << url;
122
123 QStringList groupPath = ::groupPath(url);
124
125 // is root directory?
126 if (groupPath.isEmpty()) {
127 statEntry(dirEntry(QStringLiteral(".")));
128 finished();
129 return;
130 }
131 // test subgroup
132 if (m_dataSystem->hasGroup(groupPath)) {
133 statEntry(dirEntry(groupPath.last()));
134 finished();
135 return;
136 }
137
138 // test item
139 const QString itemName = groupPath.takeLast();
140 const DataItem item = m_dataSystem->item(groupPath, itemName);
141 if (item.isValid()) {
142 statEntry(fileEntry(item));
143 finished();
144 return;
145 }
146
147 error(KIO::ERR_DOES_NOT_EXIST, i18n("No such path."));
148 }
149
listDir(const QUrl & url)150 void %{APPNAME}::listDir(const QUrl &url)
151 {
152 const QStringList groupPath = ::groupPath(url);
153 qCDebug(%{APPNAMEUC}_LOG) << "%{APPNAME} starting listDir" << url << groupPath;
154
155 if (!m_dataSystem->hasGroup(groupPath)) {
156 error(KIO::ERR_DOES_NOT_EXIST, i18n("No such directory."));
157 return;
158 }
159
160 const QStringList subGroupNames = m_dataSystem->subGroupNames(groupPath);
161 const QList<DataItem> items = m_dataSystem->items(groupPath);
162
163 // report number of expected entries
164 totalSize(1 + subGroupNames.size() + items.size());
165 // own dir
166 listEntry(dirEntry(QStringLiteral(".")));
167 // subdirs
168 for (const QString &subGroupName : subGroupNames) {
169 listEntry(dirEntry(subGroupName));
170 }
171 // files
172 for (const auto &item : items) {
173 listEntry(fileEntry(item));
174 }
175 finished();
176 }
177