Chris@33
|
1
|
Chris@33
|
2 #include <QApplication>
|
Chris@33
|
3 #include <QString>
|
Chris@33
|
4 #include <QFile>
|
Chris@33
|
5 #include <QDir>
|
Chris@33
|
6
|
Chris@42
|
7 #include <QDialog>
|
Chris@42
|
8 #include <QFrame>
|
Chris@42
|
9 #include <QVBoxLayout>
|
Chris@42
|
10 #include <QCheckBox>
|
Chris@46
|
11 #include <QScrollArea>
|
Chris@42
|
12 #include <QDialogButtonBox>
|
Chris@46
|
13 #include <QLabel>
|
Chris@42
|
14
|
Chris@41
|
15 #include <vamp-hostsdk/PluginHostAdapter.h>
|
Chris@41
|
16
|
Chris@43
|
17 #include <dataquay/BasicStore.h>
|
Chris@43
|
18 #include <dataquay/RDFException.h>
|
Chris@43
|
19
|
Chris@33
|
20 #include <iostream>
|
Chris@43
|
21 #include <set>
|
Chris@43
|
22
|
Chris@33
|
23 using namespace std;
|
Chris@43
|
24 using namespace Dataquay;
|
Chris@32
|
25
|
Chris@42
|
26 QString
|
Chris@42
|
27 getDefaultInstallDirectory()
|
Chris@32
|
28 {
|
Chris@41
|
29 auto pathList = Vamp::PluginHostAdapter::getPluginPath();
|
Chris@41
|
30 if (pathList.empty()) {
|
Chris@41
|
31 cerr << "Failed to look up Vamp plugin path" << endl;
|
Chris@42
|
32 return QString();
|
Chris@41
|
33 }
|
Chris@41
|
34
|
Chris@42
|
35 auto firstPath = *pathList.begin();
|
Chris@42
|
36 QString target = QString::fromUtf8(firstPath.c_str(), firstPath.size());
|
Chris@42
|
37 return target;
|
Chris@42
|
38 }
|
Chris@42
|
39
|
Chris@42
|
40 QStringList
|
Chris@42
|
41 getPluginLibraryList()
|
Chris@42
|
42 {
|
Chris@33
|
43 QDir dir(":out/");
|
Chris@33
|
44 auto entries = dir.entryList({ "*.so", "*.dll", "*.dylib" });
|
Chris@33
|
45
|
Chris@33
|
46 for (auto e: entries) {
|
Chris@33
|
47 cerr << e.toStdString() << endl;
|
Chris@33
|
48 }
|
Chris@33
|
49
|
Chris@42
|
50 return entries;
|
Chris@42
|
51 }
|
Chris@33
|
52
|
Chris@43
|
53 unique_ptr<BasicStore>
|
Chris@43
|
54 loadLibrariesRdf()
|
Chris@43
|
55 {
|
Chris@43
|
56 QDir dir(":out/");
|
Chris@43
|
57 auto entries = dir.entryList({ "*.ttl", "*.n3" });
|
Chris@43
|
58
|
Chris@43
|
59 unique_ptr<BasicStore> store(new BasicStore);
|
Chris@43
|
60
|
Chris@43
|
61 for (auto e: entries) {
|
Chris@43
|
62
|
Chris@43
|
63 QFile f(":out/" + e);
|
Chris@43
|
64 if (!f.open(QFile::ReadOnly | QFile::Text)) {
|
Chris@43
|
65 cerr << "Failed to open RDF resource file "
|
Chris@43
|
66 << e.toStdString() << endl;
|
Chris@43
|
67 continue;
|
Chris@43
|
68 }
|
Chris@43
|
69
|
Chris@43
|
70 QByteArray content = f.readAll();
|
Chris@43
|
71 f.close();
|
Chris@43
|
72
|
Chris@43
|
73 try {
|
Chris@43
|
74 store->importString(QString::fromUtf8(content),
|
Chris@43
|
75 Uri("file:" + e),
|
Chris@43
|
76 BasicStore::ImportIgnoreDuplicates);
|
Chris@43
|
77 } catch (const RDFException &ex) {
|
Chris@43
|
78 cerr << "Failed to import RDF resource file "
|
Chris@43
|
79 << e.toStdString() << ": " << ex.what() << endl;
|
Chris@43
|
80 }
|
Chris@43
|
81 }
|
Chris@43
|
82
|
Chris@43
|
83 return store;
|
Chris@43
|
84 }
|
Chris@43
|
85
|
Chris@43
|
86 struct LibraryInfo {
|
Chris@43
|
87 QString id;
|
Chris@43
|
88 QString fileName;
|
Chris@43
|
89 QString title;
|
Chris@43
|
90 QString maker;
|
Chris@43
|
91 QString description;
|
Chris@43
|
92 };
|
Chris@43
|
93
|
Chris@43
|
94 vector<LibraryInfo>
|
Chris@43
|
95 getLibraryInfo(const Store &store, QStringList libraries)
|
Chris@43
|
96 {
|
Chris@43
|
97 /* e.g.
|
Chris@43
|
98
|
Chris@43
|
99 plugbase:library a vamp:PluginLibrary ;
|
Chris@43
|
100 vamp:identifier "qm-vamp-plugins" ;
|
Chris@43
|
101 dc:title "Queen Mary plugin set"
|
Chris@43
|
102 */
|
Chris@43
|
103
|
Chris@43
|
104 Triples tt = store.match(Triple(Node(),
|
Chris@43
|
105 Uri("a"),
|
Chris@43
|
106 store.expand("vamp:PluginLibrary")));
|
Chris@43
|
107
|
Chris@43
|
108 std::map<QString, QString> wanted; // basename -> full lib name
|
Chris@43
|
109 for (auto lib: libraries) {
|
Chris@43
|
110 wanted[QFileInfo(lib).baseName()] = lib;
|
Chris@43
|
111 }
|
Chris@43
|
112
|
Chris@43
|
113 vector<LibraryInfo> results;
|
Chris@43
|
114
|
Chris@43
|
115 for (auto t: tt) {
|
Chris@43
|
116
|
Chris@43
|
117 Node libId = store.complete(Triple(t.subject(),
|
Chris@43
|
118 store.expand("vamp:identifier"),
|
Chris@43
|
119 Node()));
|
Chris@43
|
120 if (libId.type != Node::Literal) {
|
Chris@43
|
121 continue;
|
Chris@43
|
122 }
|
Chris@43
|
123 auto wi = wanted.find(libId.value);
|
Chris@43
|
124 if (wi == wanted.end()) {
|
Chris@43
|
125 continue;
|
Chris@43
|
126 }
|
Chris@43
|
127
|
Chris@43
|
128 LibraryInfo info;
|
Chris@43
|
129 info.id = wi->first;
|
Chris@43
|
130 info.fileName = wi->second;
|
Chris@43
|
131
|
Chris@43
|
132 Node title = store.complete(Triple(t.subject(),
|
Chris@43
|
133 store.expand("dc:title"),
|
Chris@43
|
134 Node()));
|
Chris@43
|
135 if (title.type == Node::Literal) {
|
Chris@43
|
136 info.title = title.value;
|
Chris@43
|
137 } else {
|
Chris@43
|
138 info.title = info.id;
|
Chris@43
|
139 }
|
Chris@43
|
140
|
Chris@43
|
141 Node maker = store.complete(Triple(t.subject(),
|
Chris@43
|
142 store.expand("foaf:maker"),
|
Chris@43
|
143 Node()));
|
Chris@43
|
144 if (maker.type == Node::Literal) {
|
Chris@43
|
145 info.maker = maker.value;
|
Chris@46
|
146 } else if (maker != Node()) {
|
Chris@46
|
147 maker = store.complete(Triple(maker,
|
Chris@46
|
148 store.expand("foaf:name"),
|
Chris@46
|
149 Node()));
|
Chris@46
|
150 if (maker.type == Node::Literal) {
|
Chris@46
|
151 info.maker = maker.value;
|
Chris@46
|
152 }
|
Chris@43
|
153 }
|
Chris@46
|
154
|
Chris@43
|
155 Node desc = store.complete(Triple(t.subject(),
|
Chris@43
|
156 store.expand("dc:description"),
|
Chris@43
|
157 Node()));
|
Chris@43
|
158 if (desc.type == Node::Literal) {
|
Chris@43
|
159 info.description = desc.value;
|
Chris@43
|
160 }
|
Chris@43
|
161
|
Chris@43
|
162 results.push_back(info);
|
Chris@43
|
163 }
|
Chris@43
|
164
|
Chris@43
|
165 return results;
|
Chris@43
|
166 }
|
Chris@43
|
167
|
Chris@42
|
168 void
|
Chris@42
|
169 installLibrary(QString library, QString target)
|
Chris@42
|
170 {
|
Chris@42
|
171 QFile f(":out/" + library);
|
Chris@42
|
172 QString destination = target + "/" + library;
|
Chris@42
|
173 cerr << "Copying " << library.toStdString() << " to "
|
Chris@42
|
174 << destination.toStdString() << "..." << endl;
|
Chris@42
|
175 if (!f.copy(destination)) {
|
Chris@42
|
176 cerr << "Failed to copy " << library.toStdString()
|
Chris@42
|
177 << " to target " << destination.toStdString() << endl;
|
Chris@42
|
178 return;
|
Chris@42
|
179 }
|
Chris@42
|
180 if (!QFile::setPermissions
|
Chris@42
|
181 (destination,
|
Chris@42
|
182 QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
|
Chris@42
|
183 QFile::ReadGroup | QFile::ExeGroup |
|
Chris@42
|
184 QFile::ReadOther | QFile::ExeOther)) {
|
Chris@42
|
185 cerr << "Failed to set permissions on "
|
Chris@42
|
186 << library.toStdString() << endl;
|
Chris@42
|
187 return;
|
Chris@42
|
188 }
|
Chris@42
|
189 }
|
Chris@42
|
190
|
Chris@42
|
191 QStringList
|
Chris@43
|
192 getUserApprovedPluginLibraries(vector<LibraryInfo> libraries)
|
Chris@42
|
193 {
|
Chris@42
|
194 QDialog dialog;
|
Chris@46
|
195
|
Chris@46
|
196 auto mainLayout = new QGridLayout;
|
Chris@46
|
197 dialog.setLayout(mainLayout);
|
Chris@46
|
198
|
Chris@46
|
199 int mainRow = 0;
|
Chris@46
|
200
|
Chris@46
|
201 //!!! at top: title and check/uncheck all button
|
Chris@46
|
202
|
Chris@46
|
203 auto scroll = new QScrollArea;
|
Chris@46
|
204 mainLayout->addWidget(scroll, mainRow, 0, 1, 2);
|
Chris@46
|
205 mainLayout->setRowStretch(mainRow, 10);
|
Chris@46
|
206 ++mainRow;
|
Chris@46
|
207
|
Chris@46
|
208 auto selectionFrame = new QWidget;
|
Chris@46
|
209
|
Chris@46
|
210 auto selectionLayout = new QGridLayout;
|
Chris@46
|
211 selectionFrame->setLayout(selectionLayout);
|
Chris@46
|
212 int selectionRow = 0;
|
Chris@42
|
213
|
Chris@43
|
214 map<QString, QCheckBox *> checkBoxMap;
|
Chris@43
|
215
|
Chris@43
|
216 map<QString, LibraryInfo> orderedInfo;
|
Chris@43
|
217 for (auto info: libraries) {
|
Chris@43
|
218 orderedInfo[info.title] = info;
|
Chris@43
|
219 }
|
Chris@42
|
220
|
Chris@43
|
221 for (auto ip: orderedInfo) {
|
Chris@46
|
222
|
Chris@46
|
223 auto cb = new QCheckBox;
|
Chris@46
|
224 selectionLayout->addWidget(cb, selectionRow, 0, Qt::AlignTop);
|
Chris@46
|
225
|
Chris@43
|
226 LibraryInfo info = ip.second;
|
Chris@46
|
227
|
Chris@46
|
228 QString text = QObject::tr("<b>%1</b> (%2)<br><i>%3</i>")
|
Chris@46
|
229 .arg(info.title)
|
Chris@46
|
230 .arg(info.id)
|
Chris@46
|
231 .arg(info.maker);
|
Chris@46
|
232
|
Chris@46
|
233 auto label = new QLabel(text);
|
Chris@46
|
234
|
Chris@46
|
235 selectionLayout->addWidget(label, selectionRow, 1, Qt::AlignTop);
|
Chris@46
|
236
|
Chris@46
|
237 ++selectionRow;
|
Chris@46
|
238
|
Chris@43
|
239 checkBoxMap[info.fileName] = cb;
|
Chris@42
|
240 }
|
Chris@42
|
241
|
Chris@46
|
242 scroll->setWidget(selectionFrame);
|
Chris@46
|
243
|
Chris@42
|
244 auto bb = new QDialogButtonBox(QDialogButtonBox::Ok |
|
Chris@42
|
245 QDialogButtonBox::Cancel);
|
Chris@46
|
246 mainLayout->addWidget(bb, mainRow, 0, 1, 2);
|
Chris@46
|
247 ++mainRow;
|
Chris@42
|
248 QObject::connect(bb, SIGNAL(accepted()), &dialog, SLOT(accept()));
|
Chris@42
|
249 QObject::connect(bb, SIGNAL(rejected()), &dialog, SLOT(reject()));
|
Chris@42
|
250
|
Chris@42
|
251 if (dialog.exec() == QDialog::Accepted) {
|
Chris@42
|
252 cerr << "accepted" << endl;
|
Chris@42
|
253 } else {
|
Chris@42
|
254 cerr << "rejected" << endl;
|
Chris@42
|
255 }
|
Chris@42
|
256
|
Chris@42
|
257 QStringList approved;
|
Chris@42
|
258 for (const auto &p: checkBoxMap) {
|
Chris@42
|
259 if (p.second->isChecked()) {
|
Chris@42
|
260 approved.push_back(p.first);
|
Chris@33
|
261 }
|
Chris@42
|
262 }
|
Chris@42
|
263
|
Chris@42
|
264 return approved;
|
Chris@42
|
265 }
|
Chris@42
|
266
|
Chris@42
|
267 int main(int argc, char **argv)
|
Chris@42
|
268 {
|
Chris@42
|
269 QApplication app(argc, argv);
|
Chris@42
|
270
|
Chris@42
|
271 QString target = getDefaultInstallDirectory();
|
Chris@42
|
272 if (target == "") {
|
Chris@42
|
273 return 1;
|
Chris@42
|
274 }
|
Chris@42
|
275
|
Chris@42
|
276 QStringList libraries = getPluginLibraryList();
|
Chris@42
|
277
|
Chris@43
|
278 auto rdfStore = loadLibrariesRdf();
|
Chris@43
|
279
|
Chris@43
|
280 auto info = getLibraryInfo(*rdfStore, libraries);
|
Chris@43
|
281
|
Chris@43
|
282 QStringList toInstall = getUserApprovedPluginLibraries(info);
|
Chris@42
|
283
|
Chris@42
|
284 for (auto lib: toInstall) {
|
Chris@42
|
285 installLibrary(lib, target);
|
Chris@33
|
286 }
|
Chris@33
|
287
|
Chris@32
|
288 return 0;
|
Chris@32
|
289 }
|