changeset 1844:5b1b03c1d8d4

Accept more than one library URI for a plugin; consistency checks for packs
author Chris Cannam
date Mon, 20 Apr 2020 15:42:51 +0100
parents 3ec563af0a4f
children 6f626cfdba51
files rdf/PluginRDFDescription.cpp rdf/PluginRDFIndexer.cpp rdf/PluginRDFIndexer.h transform/TransformFactory.cpp
diffstat 4 files changed, 107 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- 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;
 }
 
--- 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 "
--- 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;
--- 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
 }