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