Skip navigation.
KDE Developer's Journals

A little bit of tagging

trueg's picture

For many Nepomuk is a rather abstract thing. So I will not try to explain it as a project again. I will just show what I have been up to. Randomly...

Tagging and KIO

We all know KIO and we all love it (At least I think we all do, right?). Now it was pretty obvious to create a KIO slave that allows to navigate the Nepomuk tags as folders. Writing this was not that hard. Just listing the tags and doing some plain magic around that:

QList tags = Nepomuk::Tag::allTags();
foreach(Nepomuk::Tag tag, tags ) {
    doMagic(tag);
}

So no problem there:

Nepomuk Tags KIOSlave

However, now that we can browse the tags in Dolphin, we can also rate them in Dolphin. And this is where the trouble starts: The tag URLs used in the tags KIO slave differ from their original resource URIs (remember: Nepomuk uses RDF for storage and, thus, each resource has a unique URI). The original URI looks like nepomuk://foobar while the tags KIO slave of course uses tags:/<tag name>. This is a problem since now Dolphin will store ratings and comments for the tags under the tags URI and not the original one. (this is due to the fact that KIO does not allow to have different URLs for navigation and identification, maybe this could be tackled in KDE 4.x or 5.0?)

So what to do? The simple answer is called alignment. At least that is what we call it in Nepomuk. It references a service that aligns multiple resources that actually refer to the same entity. In general this can become arbitrarily complicated. In our case, however, we can use the brute force way and simply replace tag URIs.

So now we have a kded module in playground/base/nepomuk-kde (BTW: this is where all the experimental stuff happens) that does exactly that. To give you and idea of how something like this looks a bit of code:

QString query = QString( "select distinct ?tag ?name where { "
                         "?tag a  . "
                         "?tag  ?name . "
                         "FILTER(!REGEX(STR(?tag),'^tags:/')) . }" )
                .arg( Soprano::Vocabulary::NAO::Tag().toString() )
                .arg( Nepomuk::Resource::labelUri() );
QList tagsToChange = sopranoModel()->executeQuery( query, Soprano::Query::QueryLanguageSparql ).allBindings();
foreach( Soprano::BindingSet set, tagsToChange ) {
   QUrl oldUri = set["tag"].uri();
   QString name = set["name"].toString();
   QUrl newUri = "tags:/" + name;

   QList tagStatements = sopranoModel()->listStatements( oldUri, Soprano::Node(), Soprano::Node() ).allStatements();
   foreach( Soprano::Statement s, tagStatements ) {
      sopranoModel()->removeStatement( s );
      s.setSubject( newUri );
      sopranoModel()->addStatement( s );
   }

   tagStatements = sopranoModel()->listStatements( Soprano::Node(), Soprano::Node(), oldUri ).allStatements();
   foreach( Soprano::Statement s, tagStatements ) {
      sopranoModel()->removeStatement( s );
      s.setObject( newUri );
      sopranoModel()->addStatement( s );
   }
}

This is basically how you do more advanced Nepomuk data handling. Using Soprano + SPARQL. Sadly SPARQL does not officially support update queries yet but it is a pretty new technology and we will get there.

Well, that's pretty much it. It changes the tag URIs and that results in a merge of the tag annotations with the original resource. It is a bit simple but does the job. And as a side effect: when you execute a search result that is a tag you directly come to the tags KIO slave and thus, the tagged resource. Fun, he? Ok, more on search next time.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
gemuend's picture

This is awesome! I'm looking

This is awesome! I'm looking forward to having nice GUIs around all those features. KDE might be the first desktop to _really_ take the idea of the semantic web to the desktop. Rock on!

vladc's picture

Lack of URL translation by KIO hurts KioFuse & chained KIO slave

The tag URLs used in the tags KIO slave differ from their original resource URIs

This is the same deficiency in KIO that I am running into while attempting to make KIO aware of KioFuse mounts. Currently, KioFuse gives 'virtual' KIO resources such as sftp:/, smb:/ or tar:/ a permanent mountpoint within the root filesystem. For example, "sftp://school.edu/home/username" can be mounted as "~/network/school" on the local computer. The problem is that when KIO accesses "~/network/school" it doesn't realize that this directory is actually "sftp://school.edu/home/username", and it tries to use POSIX commands to access this directory. This unnecessary indirection causes a performance penalty and some feature limitations. It would be much better if KIO could translate "~/network/school" back to "sftp://school.edu/home/username" and use the KIO slave directly.

Another advantage of KIO being able to transparently translate URLs would be the elimination of ambiguous nested (chained) URLs. Say you have a file essay.txt saved in bundle.tar compressed as surprise.bz2 saved on sftp://school.edu/home/username.

First you'd mount sftp://school.edu/home/username in ~/network/school. Then you'd mount ~/network/school/surprise.bz2 in ~/archives/surprise. Then you'd mount ~/archives/surprise/bundle.tar in ~/archives/bundle and your file will be accessible as ~/archives/bundle/essay.txt.

Overall, I think a common solution for URL translation in KIO that fits the needs of Nepomuk, Strigi and KioFuse is the best outcome.

smarter's picture

Virtual search directories?

That's cool! Could you combine this with strigi to create "virtual search directories" containing the result of a search?

oever's picture

Re: Virtual search directories?

This is a separate issues and has actually been done in the past. Technically it is easy. What would be most work is to make a userfriendly GUI for configuration of such folders. Once we have a better search GUI we could add a function there along the lines of 'Store search as folder...'.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.