# HG changeset patch # User Chris Cannam # Date 1587393771 -3600 # Node ID 5b1b03c1d8d47819570f481fc7582e4dbfc3d527 # Parent 3ec563af0a4fe1c215e3697ad08b2c6f3649e12a Accept more than one library URI for a plugin; consistency checks for packs diff -r 3ec563af0a4f -r 5b1b03c1d8d4 rdf/PluginRDFDescription.cpp --- a/rdf/PluginRDFDescription.cpp Fri Apr 17 17:45:34 2020 +0100 +++ b/rdf/PluginRDFDescription.cpp Mon Apr 20 15:42:51 2020 +0100 @@ -32,6 +32,8 @@ using Dataquay::Triples; using Dataquay::BasicStore; +#define DEBUG_PLUGIN_RDF_DESCRIPTION 1 + PluginRDFDescription::PluginRDFDescription(QString pluginId) : m_pluginId(pluginId), m_haveDescription(false) @@ -235,23 +237,37 @@ m_pluginInfoURL = n.value; } - Node libn = index->complete - (Triple(Node(), index->expand("vamp:available_plugin"), plugin)); + // There may be more than one library node claiming this + // plugin. That's because older RDF descriptions tend to use a + // library node URI derived from the description's own URI, so it + // varies depending on where you read the description from. It's + // common therefore to end up with both a file: URI (from an + // installed older version) and an http: one (from an online + // updated version). We have no way to pick an authoritative one, + // but it's also common that only one of them will have the + // resources we need anyway, so let's iterate through them all. + + Nodes libnodes = index->match + (Triple(Node(), index->expand("vamp:available_plugin"), plugin)) + .subjects(); - if (libn.value != "") { + for (Node libn: libnodes) { + + if (libn.type != Node::URI || libn.value == "") { + continue; + } n = index->complete (Triple(libn, index->expand("foaf:page"), Node())); - if (n.type == Node::URI && n.value != "" && m_pluginInfoURL == "") { + + if (n.type == Node::URI && n.value != "") { m_pluginInfoURL = n.value; } - // And the download page for the library n = index->complete (Triple(libn, index->expand("doap:download-page"), Node())); if (n.type == Node::URI && n.value != "") { - m_pluginDownloadURL = n.value; n = index->complete @@ -277,32 +293,56 @@ } } } + + Nodes packs = index->match + (Triple(Node(), index->expand("vamp:available_library"), libn)) + .subjects(); + + SVCERR << packs.size() << " matching pack(s) for library node " + << libn << endl; + + for (Node packn: packs) { + if (packn.type != Node::URI) continue; + + Pack pack; + n = index->complete + (Triple(packn, index->expand("dc:title"), Node())); + if (n.type == Node::Literal) { + pack.name = n.value; + } + n = index->complete + (Triple(packn, index->expand("foaf:page"), Node())); + if (n.type == Node::URI) { + pack.downloadURL = n.value; + } + + if (pack.name != "" && pack.downloadURL != "") { + m_pluginFoundInPacks[packn.value] = pack; + } + } } - Nodes packs = index->match - (Triple(Node(), index->expand("vamp:available_library"), libn)) - .objects(); +#ifdef DEBUG_PLUGIN_RDF_DESCRIPTION + SVCERR << "PluginRDFDescription::indexMetadata:" << endl; + SVCERR << " * id: " << m_pluginId << endl; + SVCERR << " * uri: <" << m_pluginUri << ">" << endl; + SVCERR << " * name: " << m_pluginName << endl; + SVCERR << " * description: " << m_pluginDescription << endl; + SVCERR << " * maker: " << m_pluginMaker << endl; + SVCERR << " * info url: <" << m_pluginInfoURL << ">" << endl; + SVCERR << " * download url: <" << m_pluginDownloadURL << ">" << endl; + SVCERR << " * download types:" << endl; + for (auto t: m_pluginDownloadTypes) { + SVCERR << " * " << int(t) << endl; + } + SVCERR << " * packs:" << endl; + for (auto t: m_pluginFoundInPacks) { + SVCERR << " * " << t.first << " { name: " << t.second.name + << ", download url: " << t.second.downloadURL << " }" << endl; + } + SVCERR << endl; +#endif - for (Node packn: packs) { - if (packn.type != Node::URI) continue; - - Pack pack; - n = index->complete - (Triple(packn, index->expand("dc:title"), Node())); - if (n.type == Node::Literal) { - pack.name = n.value; - } - n = index->complete - (Triple(packn, index->expand("foaf:page"), Node())); - if (n.type == Node::URI) { - pack.downloadURL = n.value; - } - - if (pack.name != "" && pack.downloadURL != "") { - m_pluginFoundInPacks[packn.value] = pack; - } - } - return true; } diff -r 3ec563af0a4f -r 5b1b03c1d8d4 rdf/PluginRDFIndexer.cpp --- a/rdf/PluginRDFIndexer.cpp Fri Apr 17 17:45:34 2020 +0100 +++ b/rdf/PluginRDFIndexer.cpp Mon Apr 20 15:42:51 2020 +0100 @@ -181,9 +181,31 @@ settings.endGroup(); reindex(); + return true; } +void +PluginRDFIndexer::performConsistencyChecks() +{ + // Add more here! + + Triples packs = m_index->match + (Triple(Node(), m_index->expand("vamp:available_library"), Node())); + + for (Triple packt: packs) { + Triples libraries = m_index->match + (Triple(packt.object(), m_index->expand("a"), + m_index->expand("vamp:PluginLibrary"))); + if (libraries.empty()) { + SVCERR << "WARNING: Plugin pack " << packt.subject() + << " claims to contain library " << packt.object() + << " which is not known to us as a vamp:PluginLibrary" + << endl; + } + } +} + QString PluginRDFIndexer::getURIForPluginId(QString pluginId) { @@ -288,12 +310,7 @@ } try { - m_index->import(local, BasicStore::ImportFailOnDuplicates); - } catch (RDFDuplicateImportException &e) { - SVDEBUG << e.what() << endl; - SVDEBUG << "PluginRDFIndexer::pullURL: Document at " << urlString - << " duplicates triples found in earlier loaded document -- skipping it" << endl; - return false; + m_index->import(local, BasicStore::ImportIgnoreDuplicates); } catch (RDFException &e) { SVDEBUG << e.what() << endl; SVDEBUG << "PluginRDFIndexer::pullURL: Failed to import document from " diff -r 3ec563af0a4f -r 5b1b03c1d8d4 rdf/PluginRDFIndexer.h --- a/rdf/PluginRDFIndexer.h Fri Apr 17 17:45:34 2020 +0100 +++ b/rdf/PluginRDFIndexer.h Mon Apr 20 15:42:51 2020 +0100 @@ -52,6 +52,12 @@ QStringList getIndexedPluginIds(); + /** + * Perform various checks for consistency of RDF definitions, + * printing warnings to stderr/logfile as appropriate. + */ + void performConsistencyChecks(); + const Dataquay::BasicStore *getIndex(); ~PluginRDFIndexer(); @@ -69,7 +75,7 @@ bool pullFile(QString path); bool pullURL(QString urlString); bool reindex(); - + Dataquay::BasicStore *m_index; static PluginRDFIndexer *m_instance; diff -r 3ec563af0a4f -r 5b1b03c1d8d4 transform/TransformFactory.cpp --- a/transform/TransformFactory.cpp Fri Apr 17 17:45:34 2020 +0100 +++ b/transform/TransformFactory.cpp Mon Apr 20 15:42:51 2020 +0100 @@ -642,6 +642,8 @@ PluginRDFIndexer::getInstance()->indexConfiguredURLs(); if (m_exiting) return; + PluginRDFIndexer::getInstance()->performConsistencyChecks(); + //!!! This will be amazingly slow QStringList ids = PluginRDFIndexer::getInstance()->getIndexedPluginIds(); @@ -653,7 +655,7 @@ QString name = desc.getPluginName(); #ifdef DEBUG_TRANSFORM_FACTORY if (name == "") { - cerr << "TransformFactory::populateUninstalledTransforms: " + SVCERR << "TransformFactory::populateUninstalledTransforms: " << "No name available for plugin " << *i << ", skipping" << endl; continue; @@ -672,8 +674,8 @@ if (m_transforms.find(tid) != m_transforms.end()) { #ifdef DEBUG_TRANSFORM_FACTORY - cerr << "TransformFactory::populateUninstalledTransforms: " - << tid << " is installed; adding info url if appropriate, skipping rest" << endl; + SVCERR << "TransformFactory::populateUninstalledTransforms: " + << tid << " is installed; adding info url if appropriate, skipping rest" << endl; #endif if (infoUrl != "") { if (m_transforms[tid].infoUrl == "") { @@ -684,8 +686,8 @@ } #ifdef DEBUG_TRANSFORM_FACTORY - cerr << "TransformFactory::populateUninstalledTransforms: " - << "adding " << tid << endl; + SVCERR << "TransformFactory::populateUninstalledTransforms: " + << "adding " << tid << endl; #endif QString oname = desc.getOutputName(*j); @@ -739,7 +741,7 @@ m_uninstalledTransformsPopulated = true; #ifdef DEBUG_TRANSFORM_FACTORY - cerr << "populateUninstalledTransforms exiting" << endl; + SVCERR << "populateUninstalledTransforms exiting" << endl; #endif }