annotate rdf/PluginRDFDescription.cpp @ 1843:3ec563af0a4f

Retrieve download URL, download type, and "pack" information
author Chris Cannam
date Fri, 17 Apr 2020 17:45:34 +0100
parents e802e550a1f2
children 5b1b03c1d8d4
rev   line source
Chris@439 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@439 2
Chris@439 3 /*
Chris@439 4 Sonic Visualiser
Chris@439 5 An audio file viewer and annotation editor.
Chris@439 6 Centre for Digital Music, Queen Mary, University of London.
Chris@727 7 This file copyright 2008-2012 QMUL.
Chris@439 8
Chris@439 9 This program is free software; you can redistribute it and/or
Chris@439 10 modify it under the terms of the GNU General Public License as
Chris@439 11 published by the Free Software Foundation; either version 2 of the
Chris@439 12 License, or (at your option) any later version. See the file
Chris@439 13 COPYING included with this distribution for more information.
Chris@439 14 */
Chris@439 15
Chris@439 16 #include "PluginRDFDescription.h"
Chris@439 17
Chris@439 18 #include "PluginRDFIndexer.h"
Chris@439 19
Chris@457 20 #include "base/Profiler.h"
Chris@457 21
Chris@439 22 #include "plugin/PluginIdentifier.h"
Chris@439 23
Chris@725 24 #include <dataquay/BasicStore.h>
Chris@725 25
Chris@439 26 #include <iostream>
Chris@439 27
Chris@725 28 using Dataquay::Uri;
Chris@725 29 using Dataquay::Node;
Chris@725 30 using Dataquay::Nodes;
Chris@725 31 using Dataquay::Triple;
Chris@725 32 using Dataquay::Triples;
Chris@725 33 using Dataquay::BasicStore;
Chris@725 34
Chris@439 35 PluginRDFDescription::PluginRDFDescription(QString pluginId) :
Chris@439 36 m_pluginId(pluginId),
Chris@439 37 m_haveDescription(false)
Chris@439 38 {
Chris@439 39 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
Chris@489 40 m_pluginUri = indexer->getURIForPluginId(pluginId);
Chris@489 41 if (m_pluginUri == "") {
Chris@439 42 cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \""
Chris@686 43 << pluginId << "\"" << endl;
Chris@439 44 } else {
Chris@489 45 // All the data we need should be in our RDF model already:
Chris@489 46 // if it's not there, we don't know where to find it anyway
Chris@489 47 if (index()) {
Chris@439 48 m_haveDescription = true;
Chris@439 49 }
Chris@439 50 }
Chris@439 51 }
Chris@439 52
Chris@439 53 PluginRDFDescription::~PluginRDFDescription()
Chris@439 54 {
Chris@439 55 }
Chris@439 56
Chris@439 57 bool
Chris@439 58 PluginRDFDescription::haveDescription() const
Chris@439 59 {
Chris@439 60 return m_haveDescription;
Chris@439 61 }
Chris@439 62
Chris@457 63 QString
Chris@457 64 PluginRDFDescription::getPluginName() const
Chris@457 65 {
Chris@457 66 return m_pluginName;
Chris@457 67 }
Chris@457 68
Chris@457 69 QString
Chris@457 70 PluginRDFDescription::getPluginDescription() const
Chris@457 71 {
Chris@457 72 return m_pluginDescription;
Chris@457 73 }
Chris@457 74
Chris@457 75 QString
Chris@457 76 PluginRDFDescription::getPluginMaker() const
Chris@457 77 {
Chris@457 78 return m_pluginMaker;
Chris@457 79 }
Chris@457 80
Chris@462 81 QString
Chris@462 82 PluginRDFDescription::getPluginInfoURL() const
Chris@462 83 {
Chris@462 84 return m_pluginInfoURL;
Chris@462 85 }
Chris@462 86
Chris@1843 87 QString
Chris@1843 88 PluginRDFDescription::getPluginDownloadURL() const
Chris@1843 89 {
Chris@1843 90 return m_pluginDownloadURL;
Chris@1843 91 }
Chris@1843 92
Chris@1843 93 std::set<PluginRDFDescription::DownloadType>
Chris@1843 94 PluginRDFDescription::getPluginDownloadTypes() const
Chris@1843 95 {
Chris@1843 96 return m_pluginDownloadTypes;
Chris@1843 97 }
Chris@1843 98
Chris@1843 99 std::map<QString, PluginRDFDescription::Pack>
Chris@1843 100 PluginRDFDescription::getPluginFoundInPacks() const
Chris@1843 101 {
Chris@1843 102 return m_pluginFoundInPacks;
Chris@1843 103 }
Chris@1843 104
Chris@457 105 QStringList
Chris@457 106 PluginRDFDescription::getOutputIds() const
Chris@457 107 {
Chris@457 108 QStringList ids;
Chris@457 109 for (OutputDispositionMap::const_iterator i = m_outputDispositions.begin();
Chris@457 110 i != m_outputDispositions.end(); ++i) {
Chris@457 111 ids.push_back(i->first);
Chris@457 112 }
Chris@457 113 return ids;
Chris@457 114 }
Chris@457 115
Chris@457 116 QString
Chris@457 117 PluginRDFDescription::getOutputName(QString outputId) const
Chris@457 118 {
Chris@457 119 if (m_outputNames.find(outputId) == m_outputNames.end()) {
Chris@457 120 return "";
Chris@457 121 }
Chris@457 122 return m_outputNames.find(outputId)->second;
Chris@457 123 }
Chris@457 124
Chris@439 125 PluginRDFDescription::OutputDisposition
Chris@439 126 PluginRDFDescription::getOutputDisposition(QString outputId) const
Chris@439 127 {
Chris@439 128 if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) {
Chris@439 129 return OutputDispositionUnknown;
Chris@439 130 }
Chris@439 131 return m_outputDispositions.find(outputId)->second;
Chris@439 132 }
Chris@439 133
Chris@439 134 QString
Chris@439 135 PluginRDFDescription::getOutputEventTypeURI(QString outputId) const
Chris@439 136 {
Chris@439 137 if (m_outputEventTypeURIMap.find(outputId) ==
Chris@439 138 m_outputEventTypeURIMap.end()) {
Chris@439 139 return "";
Chris@439 140 }
Chris@439 141 return m_outputEventTypeURIMap.find(outputId)->second;
Chris@439 142 }
Chris@439 143
Chris@439 144 QString
Chris@440 145 PluginRDFDescription::getOutputFeatureAttributeURI(QString outputId) const
Chris@440 146 {
Chris@440 147 if (m_outputFeatureAttributeURIMap.find(outputId) ==
Chris@440 148 m_outputFeatureAttributeURIMap.end()) {
Chris@440 149 return "";
Chris@440 150 }
Chris@440 151 return m_outputFeatureAttributeURIMap.find(outputId)->second;
Chris@440 152 }
Chris@440 153
Chris@440 154 QString
Chris@440 155 PluginRDFDescription::getOutputSignalTypeURI(QString outputId) const
Chris@440 156 {
Chris@440 157 if (m_outputSignalTypeURIMap.find(outputId) ==
Chris@440 158 m_outputSignalTypeURIMap.end()) {
Chris@440 159 return "";
Chris@440 160 }
Chris@440 161 return m_outputSignalTypeURIMap.find(outputId)->second;
Chris@440 162 }
Chris@440 163
Chris@440 164 QString
Chris@439 165 PluginRDFDescription::getOutputUnit(QString outputId) const
Chris@439 166 {
Chris@439 167 if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) {
Chris@439 168 return "";
Chris@439 169 }
Chris@439 170 return m_outputUnitMap.find(outputId)->second;
Chris@439 171 }
Chris@439 172
Chris@494 173 QString
Chris@494 174 PluginRDFDescription::getOutputUri(QString outputId) const
Chris@494 175 {
Chris@494 176 if (m_outputUriMap.find(outputId) == m_outputUriMap.end()) {
Chris@494 177 return "";
Chris@494 178 }
Chris@494 179 return m_outputUriMap.find(outputId)->second;
Chris@494 180 }
Chris@494 181
Chris@439 182 bool
Chris@489 183 PluginRDFDescription::index()
Chris@439 184 {
Chris@489 185 Profiler profiler("PluginRDFDescription::index");
Chris@439 186
Chris@457 187 bool success = true;
Chris@489 188 if (!indexMetadata()) success = false;
Chris@489 189 if (!indexOutputs()) success = false;
Chris@457 190
Chris@457 191 return success;
Chris@457 192 }
Chris@457 193
Chris@457 194 bool
Chris@489 195 PluginRDFDescription::indexMetadata()
Chris@457 196 {
Chris@489 197 Profiler profiler("PluginRDFDescription::index");
Chris@489 198
Chris@725 199 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
Chris@725 200 const BasicStore *index = indexer->getIndex();
Chris@725 201 Uri plugin(m_pluginUri);
Chris@457 202
Chris@730 203 Node n = index->complete
Chris@730 204 (Triple(plugin, index->expand("vamp:name"), Node()));
Chris@730 205
Chris@725 206 if (n.type == Node::Literal && n.value != "") {
Chris@725 207 m_pluginName = n.value;
Chris@457 208 }
Chris@457 209
Chris@730 210 n = index->complete
Chris@730 211 (Triple(plugin, index->expand("dc:description"), Node()));
Chris@730 212
Chris@725 213 if (n.type == Node::Literal && n.value != "") {
Chris@725 214 m_pluginDescription = n.value;
Chris@457 215 }
Chris@457 216
Chris@730 217 n = index->complete
Chris@730 218 (Triple(plugin, index->expand("foaf:maker"), Node()));
Chris@730 219
Chris@725 220 if (n.type == Node::URI || n.type == Node::Blank) {
Chris@730 221 n = index->complete(Triple(n, index->expand("foaf:name"), Node()));
Chris@725 222 if (n.type == Node::Literal && n.value != "") {
Chris@725 223 m_pluginMaker = n.value;
Chris@725 224 }
Chris@457 225 }
Chris@457 226
Chris@462 227 // If we have a more-information URL for this plugin, then we take
Chris@725 228 // that. Otherwise, a more-information URL for the plugin library
Chris@725 229 // would do nicely.
Chris@462 230
Chris@730 231 n = index->complete
Chris@730 232 (Triple(plugin, index->expand("foaf:page"), Node()));
Chris@730 233
Chris@725 234 if (n.type == Node::URI && n.value != "") {
Chris@725 235 m_pluginInfoURL = n.value;
Chris@725 236 }
Chris@462 237
Chris@1843 238 Node libn = index->complete
Chris@730 239 (Triple(Node(), index->expand("vamp:available_plugin"), plugin));
Chris@730 240
Chris@1843 241 if (libn.value != "") {
Chris@1843 242
Chris@1843 243 n = index->complete
Chris@1843 244 (Triple(libn, index->expand("foaf:page"), Node()));
Chris@1843 245 if (n.type == Node::URI && n.value != "" && m_pluginInfoURL == "") {
Chris@1843 246 m_pluginInfoURL = n.value;
Chris@1843 247 }
Chris@1843 248
Chris@1843 249 // And the download page for the library
Chris@1843 250 n = index->complete
Chris@1843 251 (Triple(libn, index->expand("doap:download-page"), Node()));
Chris@1843 252
Chris@725 253 if (n.type == Node::URI && n.value != "") {
Chris@1843 254
Chris@1843 255 m_pluginDownloadURL = n.value;
Chris@1843 256
Chris@1843 257 n = index->complete
Chris@1843 258 (Triple(libn, index->expand("vamp:has_source"), Node()));
Chris@1843 259 if (n.type == Node::Literal && n.value == "true") {
Chris@1843 260 m_pluginDownloadTypes.insert(DownloadSourceCode);
Chris@1843 261 }
Chris@1843 262
Chris@1843 263 Nodes binaries = index->match
Chris@1843 264 (Triple(libn, index->expand("vamp:has_binary"), Node()))
Chris@1843 265 .objects();
Chris@1843 266
Chris@1843 267 for (Node bin: binaries) {
Chris@1843 268 if (bin.type != Node::Literal) continue;
Chris@1843 269 if (bin.value == "linux32") {
Chris@1843 270 m_pluginDownloadTypes.insert(DownloadLinux32);
Chris@1843 271 } else if (bin.value == "linux64") {
Chris@1843 272 m_pluginDownloadTypes.insert(DownloadLinux64);
Chris@1843 273 } else if (bin.value == "win32") {
Chris@1843 274 m_pluginDownloadTypes.insert(DownloadWindows);
Chris@1843 275 } else if (bin.value == "osx") {
Chris@1843 276 m_pluginDownloadTypes.insert(DownloadMac);
Chris@1843 277 }
Chris@1843 278 }
Chris@462 279 }
Chris@462 280 }
Chris@462 281
Chris@1843 282 Nodes packs = index->match
Chris@1843 283 (Triple(Node(), index->expand("vamp:available_library"), libn))
Chris@1843 284 .objects();
Chris@1843 285
Chris@1843 286 for (Node packn: packs) {
Chris@1843 287 if (packn.type != Node::URI) continue;
Chris@1843 288
Chris@1843 289 Pack pack;
Chris@1843 290 n = index->complete
Chris@1843 291 (Triple(packn, index->expand("dc:title"), Node()));
Chris@1843 292 if (n.type == Node::Literal) {
Chris@1843 293 pack.name = n.value;
Chris@1843 294 }
Chris@1843 295 n = index->complete
Chris@1843 296 (Triple(packn, index->expand("foaf:page"), Node()));
Chris@1843 297 if (n.type == Node::URI) {
Chris@1843 298 pack.downloadURL = n.value;
Chris@1843 299 }
Chris@1843 300
Chris@1843 301 if (pack.name != "" && pack.downloadURL != "") {
Chris@1843 302 m_pluginFoundInPacks[packn.value] = pack;
Chris@1843 303 }
Chris@1843 304 }
Chris@1843 305
Chris@457 306 return true;
Chris@457 307 }
Chris@457 308
Chris@457 309 bool
Chris@489 310 PluginRDFDescription::indexOutputs()
Chris@457 311 {
Chris@457 312 Profiler profiler("PluginRDFDescription::indexOutputs");
Chris@489 313
Chris@725 314 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
Chris@725 315 const BasicStore *index = indexer->getIndex();
Chris@725 316 Uri plugin(m_pluginUri);
Chris@457 317
Chris@730 318 Nodes outputs = index->match
Chris@730 319 (Triple(plugin, index->expand("vamp:output"), Node())).objects();
Chris@439 320
Chris@725 321 if (outputs.empty()) {
Chris@718 322 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: No outputs defined for <"
Chris@686 323 << m_pluginUri << ">" << endl;
Chris@439 324 return false;
Chris@439 325 }
Chris@439 326
Chris@725 327 foreach (Node output, outputs) {
Chris@439 328
Chris@725 329 if ((output.type != Node::URI && output.type != Node::Blank) ||
Chris@725 330 output.value == "") {
Chris@725 331 cerr << "ERROR: PluginRDFDescription::indexURL: No valid URI for output " << output << " of plugin <" << m_pluginUri << ">" << endl;
Chris@718 332 return false;
Chris@718 333 }
Chris@725 334
Chris@730 335 Node n = index->complete(Triple(output, index->expand("vamp:identifier"), Node()));
Chris@725 336 if (n.type != Node::Literal || n.value == "") {
Chris@725 337 cerr << "ERROR: PluginRDFDescription::indexURL: No vamp:identifier for output <" << output << ">" << endl;
Chris@718 338 return false;
Chris@718 339 }
Chris@725 340 QString outputId = n.value;
Chris@718 341
Chris@730 342 m_outputUriMap[outputId] = output.value;
Chris@730 343
Chris@730 344 n = index->complete(Triple(output, Uri("a"), Node()));
Chris@725 345 QString outputType;
Chris@725 346 if (n.type == Node::URI) outputType = n.value;
Chris@718 347
Chris@730 348 n = index->complete(Triple(output, index->expand("vamp:unit"), Node()));
Chris@725 349 QString outputUnit;
Chris@725 350 if (n.type == Node::Literal) outputUnit = n.value;
Chris@718 351
Chris@439 352 if (outputType.contains("DenseOutput")) {
Chris@439 353 m_outputDispositions[outputId] = OutputDense;
Chris@439 354 } else if (outputType.contains("SparseOutput")) {
Chris@439 355 m_outputDispositions[outputId] = OutputSparse;
Chris@439 356 } else if (outputType.contains("TrackLevelOutput")) {
Chris@439 357 m_outputDispositions[outputId] = OutputTrackLevel;
Chris@457 358 } else {
Chris@457 359 m_outputDispositions[outputId] = OutputDispositionUnknown;
Chris@439 360 }
Chris@732 361 // cerr << "output " << output << " -> id " << outputId << ", type " << outputType << ", unit "
Chris@732 362 // << outputUnit << ", disposition " << m_outputDispositions[outputId] << endl;
Chris@439 363
Chris@718 364 if (outputUnit != "") {
Chris@718 365 m_outputUnitMap[outputId] = outputUnit;
Chris@439 366 }
Chris@440 367
Chris@730 368 n = index->complete(Triple(output, index->expand("dc:title"), Node()));
Chris@725 369 if (n.type == Node::Literal && n.value != "") {
Chris@725 370 m_outputNames[outputId] = n.value;
Chris@457 371 }
Chris@457 372
Chris@730 373 n = index->complete(Triple(output, index->expand("vamp:computes_event_type"), Node()));
Chris@732 374 // cerr << output << " -> computes_event_type " << n << endl;
Chris@725 375 if (n.type == Node::URI && n.value != "") {
Chris@725 376 m_outputEventTypeURIMap[outputId] = n.value;
Chris@440 377 }
Chris@440 378
Chris@730 379 n = index->complete(Triple(output, index->expand("vamp:computes_feature"), Node()));
Chris@725 380 if (n.type == Node::URI && n.value != "") {
Chris@725 381 m_outputFeatureAttributeURIMap[outputId] = n.value;
Chris@725 382 }
Chris@440 383
Chris@730 384 n = index->complete(Triple(output, index->expand("vamp:computes_signal_type"), Node()));
Chris@725 385 if (n.type == Node::URI && n.value != "") {
Chris@725 386 m_outputSignalTypeURIMap[outputId] = n.value;
Chris@440 387 }
Chris@439 388 }
Chris@439 389
Chris@439 390 return true;
Chris@439 391 }
Chris@439 392