Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > media > main-testing-src > by-pkgid > a28945d3dcea70b38df270b2099e91dc > files > 2

nepomuk-kde-4.1.0-0.854049.1.2mdv2009.0.src.rpm

Index: kioslaves/tags/kio_tags.cpp
===================================================================
--- kioslaves/tags/kio_tags.cpp	(revision 879917)
+++ kioslaves/tags/kio_tags.cpp	(revision 879918)
@@ -27,11 +27,15 @@
 #include <kio/job.h>
 #include <KUser>
 #include <KDebug>
+#include <kio/netaccess.h>
 
 #include <QtCore/QEventLoop>
 
 #include <Soprano/Vocabulary/Xesam>
 #include <Soprano/Vocabulary/NAO>
+#include <Soprano/QueryResultIterator>
+#include <Soprano/Model>
+#include <Soprano/Node>
 
 
 using namespace KIO;
@@ -39,11 +43,13 @@
 
 namespace {
     KIO::UDSEntry createUDSEntryForTag( const Nepomuk::Tag& tag ) {
+        kDebug() << tag.resourceUri() << tag.genericLabel() << tag.exists();
         // create a virtual folder stat thingi
         KIO::UDSEntry uds;
         uds.insert( KIO::UDSEntry::UDS_NAME, tag.genericLabel() );
         uds.insert( KIO::UDSEntry::UDS_DISPLAY_NAME, i18n( "Things tagged with '%1'", uds.stringValue( KIO::UDSEntry::UDS_NAME ) ) );
         uds.insert( KIO::UDSEntry::UDS_CREATION_TIME, tag.property( Soprano::Vocabulary::NAO::created() ).toDateTime().toTime_t() );
+        uds.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, tag.property( Soprano::Vocabulary::NAO::lastModified() ).toDateTime().toTime_t() );
         uds.insert( KIO::UDSEntry::UDS_ACCESS, 0700 );
         uds.insert( KIO::UDSEntry::UDS_USER, KUser().loginName() );
         uds.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR );
@@ -73,37 +79,30 @@
 
 void Nepomuk::TagsProtocol::listDir( const KUrl& url )
 {
-    kDebug();
+    kDebug() << url;
 
-    // FIXME: always list all tags except the ones already in the path. These tags (subfolders)
-    // then allow to browse "Things tagged with 'A', 'B', and 'C'" and such
-
-    QString path = url.path();
-    if ( path.isEmpty() || path == "/" ) {
-        listTags();
-    }
-    else {
-        QString tag;
-        if ( splitUrl( url, tag, path ) ) {
-            if ( path.isEmpty() && !tag.isEmpty() ) {
-                listTag( tag );
-            }
-            else {
-                ForwardingSlaveBase::listDir( url );
-            }
+    QString path;
+    QStringList tags;
+    if ( splitUrl( url, tags, path ) ) {
+        if ( path.isEmpty() ) {
+            listTags( tags );
         }
+        else {
+            ForwardingSlaveBase::listDir( url );
+        }
     }
 }
 
 
 void Nepomuk::TagsProtocol::mkdir( const KUrl &url, int permissions )
 {
-    kDebug();
+    kDebug() << url;
 
-    QString tag, path;
-    if ( splitUrl( url, tag, path ) ) {
-        if ( path.isEmpty() && !tag.isEmpty() ) {
-            Tag( tag ).setLabel( tag );
+    QString path;
+    QStringList tags;
+    if ( splitUrl( url, tags, path ) ) {
+        if ( path.isEmpty() && !tags.isEmpty() ) {
+            Tag( tags.last() ).setLabel( tags.last() );
             finished();
         }
         else {
@@ -115,7 +114,7 @@
 
 void Nepomuk::TagsProtocol::get( const KUrl& url )
 {
-    kDebug();
+    kDebug() << url;
     ForwardingSlaveBase::get( url );
 }
 
@@ -133,17 +132,21 @@
 
 void Nepomuk::TagsProtocol::copy( const KUrl& src, const KUrl& dest, int permissions, KIO::JobFlags flags )
 {
-    kDebug();
-    QString tag, path;
-    if ( splitUrl( src, tag, path ) ) {
-        QString newTag, newPath;
-        if ( splitUrl( dest, newTag, newPath ) ) {
-            if ( newTag.isEmpty() ) {
+    kDebug() << src << dest;
+    QString path;
+    QStringList tags;
+    if ( splitUrl( src, tags, path ) ) {
+        QString newPath;
+        QStringList newTags;
+        if ( splitUrl( dest, newTags, newPath ) ) {
+            if ( newTags.isEmpty() ) {
                 ForwardingSlaveBase::copy( src, dest, permissions, flags );
             }
             else {
                 Resource res( path );
-                res.addTag( Tag( newTag ) );
+                foreach( const QString& tag, newTags ) {
+                    res.addTag( Tag( tag ) );
+                }
                 finished();
             }
         }
@@ -153,17 +156,19 @@
 
 void Nepomuk::TagsProtocol::rename( const KUrl& src, const KUrl& dest, KIO::JobFlags flags )
 {
-    kDebug();
-    QString tag, path;
-    if ( splitUrl( src, tag, path ) ) {
+    kDebug() << src << dest;
+    QString path;
+    QStringList tags;
+    if ( splitUrl( src, tags, path ) ) {
         if ( path.isEmpty() ) {
-            QString newTag, newPath;
-            if ( splitUrl( dest, newTag, newPath ) ) {
-                if ( !newTag.isEmpty() ) {
+            QString newPath;
+            QStringList newTags;
+            if ( splitUrl( dest, newTags, newPath ) ) {
+                if ( path.isEmpty() && !newTags.isEmpty() ) {
                     // rename tag
-                    Tag theTag( tag );
-                    theTag.setLabel( newTag );
-                    theTag.setIdentifiers( QStringList( newTag ) );
+                    Tag theTag( tags.last() );
+                    theTag.setLabel( newTags.last() );
+                    theTag.setIdentifiers( QStringList( newTags.last() ) );
                     finished();
                 }
                 else {
@@ -180,25 +185,35 @@
 
 void Nepomuk::TagsProtocol::del( const KUrl& url, bool isfile )
 {
-    kDebug();
-    QString tag, path;
-    if ( splitUrl( url, tag, path ) ) {
-        if ( tag.isEmpty() ) {
+    kDebug() << url << isfile;
+    QString path;
+    QStringList tags;
+    if ( splitUrl( url, tags, path ) ) {
+        if ( tags.isEmpty() ) {
             ForwardingSlaveBase::del( url, isfile );
         }
         else {
             if ( path.isEmpty() ) {
                 // delete the tag altogether
-                Tag( tag ).remove();
+                Tag( tags.last() ).remove();
                 finished();
             }
             else {
-                // "untag" the file
-                Resource res( path );
-                QList<Tag> tags = res.tags();
-                tags.removeAll( Tag( tag ) );
-                res.setTags( tags );
-                finished();
+                // "untag" the resource
+                KUrl targetUrl;
+                if ( rewriteUrl( url, targetUrl ) ) {
+                    Resource res( targetUrl );
+                    if ( res.isValid() ) {
+                        QList<Tag> currentTags = res.tags();
+                        foreach( const QString& tag, tags ) {
+                            currentTags.removeAll( Tag( tag ) );
+                        }
+                        res.setTags( currentTags );
+                        finished();
+                        return;
+                    }
+                }
+                error( ERR_MALFORMED_URL, url.url() );
             }
         }
     }
@@ -207,14 +222,14 @@
 
 void Nepomuk::TagsProtocol::mimetype( const KUrl& url )
 {
-    kDebug();
-    QString tag;
+    kDebug() << url;
+    QStringList tags;
     QString path = url.path();
     if ( path.isEmpty() || path == "/" ) {
         mimeType( "inode/directory" );
         finished();
     }
-    else if ( splitUrl( url, tag, path ) ) {
+    else if ( splitUrl( url, tags, path ) ) {
         if ( path.isEmpty() ) {
             mimeType( "inode/directory" );
             finished();
@@ -228,7 +243,7 @@
 
 void Nepomuk::TagsProtocol::stat( const KUrl& url )
 {
-    kDebug();
+    kDebug() << url;
     QString path = url.path();
     if ( path.isEmpty() || path == "/" ) {
         //
@@ -243,15 +258,15 @@
         finished();
     }
     else {
-        QString tag;
-        if ( splitUrl( url, tag, path ) ) {
+        QStringList tags;
+        if ( splitUrl( url, tags, path ) ) {
             if ( path.isEmpty() ) {
-                statEntry( createUDSEntryForTag( Tag( tag ) ) );
+                statEntry( createUDSEntryForTag( tags.last() ) );
             }
             else {
                 KUrl newUrl;
                 rewriteUrl( url, newUrl );
-                statEntry( statFile( newUrl ) );
+                statEntry( statResource( newUrl ) );
             }
         }
         finished();
@@ -261,20 +276,18 @@
 
 bool Nepomuk::TagsProtocol::rewriteUrl( const KUrl& url, KUrl& newURL )
 {
-    kDebug();
-    QString tag, path;
-    if ( splitUrl( url, tag, path, false ) ) {
-        if ( !tag.isEmpty() ) {
+    kDebug() << url;
+    QString path;
+    QStringList tags;
+    if ( splitUrl( url, tags, path, false ) ) {
+        if ( !tags.isEmpty() ) {
             // HACK
-            // FIXME: This is no solution, especially because path is not unique!
-            Tag t( tag );
+            // FIXME: Create a correct sparql query
+            Tag t( tags.last() );
             foreach( Resource res, t.tagOf() ) {
-                if ( res.hasProperty( Soprano::Vocabulary::Xesam::url().toString() ) ) {
-                    QString p = res.property( Soprano::Vocabulary::Xesam::url().toString() ).toStringList().first();
-                    if ( p.endsWith( path ) ) {
-                        newURL = p;
-                        return true;
-                    }
+                if ( res.genericLabel() == path ) {
+                    newURL = res.resourceUri();
+                    return true;
                 }
             }
         }
@@ -288,26 +301,33 @@
 }
 
 
-bool Nepomuk::TagsProtocol::splitUrl( const KUrl& url, QString& tag, QString& path, bool signalError )
+bool Nepomuk::TagsProtocol::splitUrl( const KUrl& url, QStringList& tags, QString& fileName, bool signalError )
 {
-    kDebug();
-    path = url.path().mid( 1 );
-    int pos = path.indexOf( '/' );
-    if ( pos > 0 ) {
-        tag = path.left( pos );
-        path = path.mid( pos );
-        if ( path.endsWith( "/" ) )
-            path.truncate( path.length()-1 );
-        return true;
+    kDebug() << url;
+    fileName = url.fileName( KUrl::ObeyTrailingSlash );
+    QString dir = url.directory( KUrl::ObeyTrailingSlash );
+    tags = dir.split( '/', QString::SkipEmptyParts );
+
+    // we need to check if there is a tag called fileName. I don't think there is another way
+    if ( !fileName.isEmpty() ) {
+        if ( ResourceManager::instance()->mainModel()->executeQuery( QString( "ask where { ?r a <%1> . { ?r <%2> %3 . } UNION { ?r <%4> %3 . } }" )
+                                                                     .arg( Soprano::Vocabulary::NAO::Tag().toString() )
+                                                                     .arg( Soprano::Vocabulary::NAO::prefLabel().toString() )
+                                                                     .arg( Soprano::Node( Soprano::LiteralValue( fileName ) ).toN3() )
+                                                                     .arg( Soprano::Vocabulary::NAO::identifier().toString() ),
+                                                                     Soprano::Query::QueryLanguageSparql ).boolValue() ) {
+            tags << fileName;
+            fileName = QString();
+        }
     }
-    else if ( !path.isEmpty() ) {
-        tag = path;
-        path = QString();
+
+    if ( fileName.isEmpty() || !tags.isEmpty() ) {
+        kDebug() << url << tags << fileName;
         return true;
     }
     else {
         if ( signalError ) {
-            error( ERR_MALFORMED_URL, i18n( "Unable to handle URL %1" ).arg( url.path() ) );
+            error( ERR_MALFORMED_URL, i18n( "Unable to handle URL %1", url.url() ) );
         }
 
         return false;
@@ -315,111 +335,130 @@
 }
 
 
-
-void Nepomuk::TagsProtocol::listTags()
+void Nepomuk::TagsProtocol::listTags( const QStringList& tagLabels )
 {
-    kDebug();
-    QList<Tag> tags = Tag::allTags();
+    kDebug() << tagLabels;
 
-//    totalSize( tags.count() );
+    // list tagged things
+    QList<Tag> tags;
+    if ( !tagLabels.isEmpty() ) {
+        QString query = "select ?r where { ";
+        foreach( const QString& tag, tagLabels ) {
+            tags << Tag( tag );
+            query += QString( "?r <%1> <%2> . " )
+                     .arg( Soprano::Vocabulary::NAO::hasTag().toString() )
+                     .arg( QString::fromAscii( tags.last().resourceUri().toEncoded() ) );
+        }
+        query += '}';
+        kDebug() << query;
+        Soprano::QueryResultIterator it = ResourceManager::instance()->mainModel()->executeQuery( query, Soprano::Query::QueryLanguageSparql );
+        while ( it.next() ) {
+            listEntry( statResource( it.binding( 0 ).uri() ), false );
+        }
+    }
 
-    for ( QList<Tag>::iterator it = tags.begin();
-          it != tags.end(); ++it ) {
-        listEntry( createUDSEntryForTag( *it ), false );
+
+    // list sub-folders
+    QList<Tag> allTags = Tag::allTags();
+    for ( QList<Tag>::iterator it = allTags.begin();
+          it != allTags.end(); ++it ) {
+        if ( !tags.contains( *it ) ) {
+            kDebug() << "listing subfolder" << it->resourceUri() << it->genericLabel() << it->exists();
+            listEntry( createUDSEntryForTag( *it ), false );
+        }
+        else {
+            kDebug() << "NOT listing subfolder" << it->resourceUri() << it->genericLabel() << it->exists();
+        }
     }
 
+
     listEntry( KIO::UDSEntry(), true );
 
     finished();
 }
 
 
-void Nepomuk::TagsProtocol::listTag( const QString& tag )
+KIO::UDSEntry Nepomuk::TagsProtocol::statResource( const QUrl& uri )
 {
-    kDebug() << ": " << tag;
-    m_currentTag = tag;
+    kDebug() << uri;
 
-    Tag theTag( tag );
-    QList<Resource> taggedOnes = theTag.tagOf();
+    KIO::UDSEntry uds;
 
-    // FIXME: use the search io slave code for resource listing
-    // FIXME: why can't we just use ForwardingSlaveBase to list result files? Probably the same reason as in the search io slave?
-    for ( QList<Resource>::const_iterator it = taggedOnes.constBegin();
-          it != taggedOnes.constEnd(); ++it ) {
-        const Resource& res = *it;
-        if ( res.hasProperty( Soprano::Vocabulary::Xesam::url().toString() ) ) {
-            listEntry( statFile( KUrl( res.property( Soprano::Vocabulary::Xesam::url().toString() ).toStringList().first() ) ), false );
+    Nepomuk::Resource res( uri );
+    KUrl url = res.property( Soprano::Vocabulary::Xesam::url() ).toString();
+    if ( url.isEmpty() ) {
+        url = uri;
+    }
+    bool isFile = false;
+    if ( !url.isEmpty() && url.scheme() != "akonadi" ) { // do not stat akonadi resouces here, way too slow, even hangs if akonadi is not running
+        kDebug() << "listing file" << url;
+        if ( KIO::StatJob* job = KIO::stat( url, KIO::HideProgressInfo ) ) {
+            job->setAutoDelete( false );
+            if ( KIO::NetAccess::synchronousRun( job, 0 ) ) {
+                uds = job->statResult();
+                if ( url.isLocalFile() ) {
+                    uds.insert( KIO::UDSEntry::UDS_LOCAL_PATH, url.toLocalFile() );
+                }
+                isFile = true;
+            }
+            else {
+                kDebug() << "failed to stat" << url;
+            }
+            delete job;
         }
     }
 
-    listEntry( KIO::UDSEntry(), true );
-    finished();
-}
+    //
+    // The nepomuk resource listing is the same as in the nepomuk kio slave.
+    // So either only depend on that or let the nepomuk kio slave fail on each
+    // stat.
+    //
+    if ( !isFile ) {
+        kDebug() << "listing resource" << uri;
 
+        QString label = res.genericLabel();
+        QString name = label;
 
-KIO::UDSEntry Nepomuk::TagsProtocol::statFile( const KUrl& url )
-{
-    m_currentUrl = url;
-    m_currentUDS.clear();
+        // make sure name is not the URI (which is the fallback of genericLabel() and will lead to crashes in KDirModel)
+        if ( name.contains( '/' ) ) {
+            name = name.section( '/', -1 );
+            if ( name.isEmpty() )
+                name = res.resourceUri().fragment();
+            if ( name.isEmpty() )
+                name = res.resourceUri().toString().replace( '/', '_' );
+        }
 
-    KIO::StatJob* job = KIO::stat( m_currentUrl, KIO::HideProgressInfo );
-    connect( job, SIGNAL( result(KJob *) ),
-             this, SLOT( slotResult(KJob *) ) );
-    connect( job, SIGNAL( redirection(KIO::Job *, const KUrl &) ),
-             this, SLOT( slotRedirection(KIO::Job *, const KUrl &) ) );
-
-    m_eventLoop.exec();
-
-    return m_currentUDS;
-}
-
-
-// taken from ForwardingSlaveBase
-void Nepomuk::TagsProtocol::slotResult( KJob* job )
-{
-    kDebug();
-    if ( job->error() != 0 ) {
-        error( job->error(), job->errorText() );
-    }
-    else {
-        KIO::StatJob* stat_job = qobject_cast<KIO::StatJob*>(job);
-        if ( stat_job != 0 ) {
-            // FIXME: The name is not unique here! This is a problem especially for
-            // rewriteUrl since then the URL is also not unique
-            m_currentUDS = stat_job->statResult();
-            m_currentUDS.insert( KIO::UDSEntry::UDS_LOCAL_PATH, m_currentUrl.path() );
-            m_currentUDS.insert( KIO::UDSEntry::UDS_TARGET_URL, m_currentUrl.url() );
+        uds.insert( KIO::UDSEntry::UDS_NAME, name );
+        uds.insert( KIO::UDSEntry::UDS_DISPLAY_NAME, label );
+        uds.insert( KIO::UDSEntry::UDS_CREATION_TIME, res.property( Soprano::Vocabulary::NAO::created() ).toDateTime().toTime_t() );
+        uds.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, res.property( Soprano::Vocabulary::NAO::lastModified() ).toDateTime().toTime_t() );
+        uds.insert( KIO::UDSEntry::UDS_ACCESS, 0700 );
+        uds.insert( KIO::UDSEntry::UDS_USER, KUser().loginName() );
+        uds.insert( KIO::UDSEntry::UDS_MIME_TYPE, "application/x-nepomuk-resource" );
+        QString icon = res.genericIcon();
+        if ( !icon.isEmpty() ) {
+            uds.insert( KIO::UDSEntry::UDS_ICON_NAME, icon );
         }
     }
 
-    m_eventLoop.exit();
-}
+    uds.insert( KIO::UDSEntry::UDS_TARGET_URL, uri.toString() );
 
+    //
+    // FIXME: make sure we have no duplicate names
+    //
 
-// taken from ForwardingSlaveBase
-void Nepomuk::TagsProtocol::slotRedirection( KIO::Job *job, const KUrl& url )
-{
-    kDebug();
-    redirection(url);
-
-    // We've been redirected stop everything.
-    job->kill( KJob::Quietly );
-    finished();
-
-    m_eventLoop.exit();
+    return uds;
 }
 
 
-
 extern "C"
 {
     KDE_EXPORT int kdemain( int argc, char **argv )
     {
-        KAboutData about( "kio_tags", 0, ki18n("kio_tags"), 0);
-        KCmdLineArgs::init( &about );
+        // necessary to use other kio slaves
+        KComponentData( "kio_nepomuksearch" );
+        QCoreApplication app( argc, argv );
 
-        KApplication app;
-
         kDebug(7102) << "Starting tags slave " << getpid();
 
         if (argc != 4) {
Index: kioslaves/tags/kio_tags.h
===================================================================
--- kioslaves/tags/kio_tags.h	(revision 879917)
+++ kioslaves/tags/kio_tags.h	(revision 879918)
@@ -84,21 +84,10 @@
          */
         bool rewriteUrl( const KUrl& url, KUrl& newURL );
 
-    private Q_SLOTS:
-        void slotRedirection( KIO::Job *job, const KUrl& url );
-        void slotResult( KJob* job );
-
     private:
-        bool splitUrl( const KUrl& url, QString& tag, QString& path, bool signalError = true );
-        void listTags();
-        void listTag( const QString& tag );
-        KIO::UDSEntry statFile( const KUrl& url );
-
-        QString m_currentTag;
-        KUrl m_currentUrl;
-        KIO::UDSEntry m_currentUDS;
-
-        QEventLoop m_eventLoop;
+        bool splitUrl( const KUrl& url, QStringList& tags, QString& path, bool signalError = true );
+        void listTags( const QStringList& tags = QStringList() );
+        KIO::UDSEntry statResource( const QUrl& uri );
     };
 }