• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

NepomukDaemons

kio_nepomuksearch.cpp

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 2008 by Sebastian Trueg <trueg at kde.org>
00003 
00004    This program is free software; you can redistribute it and/or modify
00005    it under the terms of the GNU General Public License as published by
00006    the Free Software Foundation; either version 2, or (at your option)
00007    any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012    GNU General Public License for more details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017  */
00018 
00019 #include "kio_nepomuksearch.h"
00020 #include "searchfolder.h"
00021 
00022 #include <QtCore/QFile>
00023 
00024 #include <KUser>
00025 #include <KDebug>
00026 #include <KAboutData>
00027 #include <KApplication>
00028 #include <KCmdLineArgs>
00029 #include <kio/global.h>
00030 #include <kio/job.h>
00031 #include <KMimeType>
00032 
00033 #include <Nepomuk/Resource>
00034 #include <Nepomuk/ResourceManager>
00035 #include <Nepomuk/Variant>
00036 #include "queryparser.h"
00037 
00038 #include <Soprano/Vocabulary/RDF>
00039 #include <Soprano/Vocabulary/Xesam>
00040 
00041 #include <sys/types.h>
00042 #include <unistd.h>
00043 
00044 
00045 namespace {
00046     KIO::UDSEntry statDefaultSearchFolder( const QString& name ) {
00047         KIO::UDSEntry uds;
00048         uds.insert( KIO::UDSEntry::UDS_NAME, name );
00049         uds.insert( KIO::UDSEntry::UDS_ACCESS, 0700 );
00050         uds.insert( KIO::UDSEntry::UDS_USER, KUser().loginName() );
00051         uds.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR );
00052         uds.insert( KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1( "inode/directory" ) );
00053         return uds;
00054     }
00055 
00056     // do not cache more than SEARCH_CACHE_MAX search folders at the same time
00057     const int SEARCH_CACHE_MAX = 5;
00058 }
00059 
00060 
00061 Nepomuk::SearchProtocol::SearchProtocol( const QByteArray& poolSocket, const QByteArray& appSocket )
00062     : KIO::ForwardingSlaveBase( "nepomuksearch", poolSocket, appSocket )
00063 {
00064     // FIXME: load default searches from config
00065     // FIXME: allow icons
00066 
00067     // all music files
00068     addDefaultSearch( i18n( "All Music Files" ), Search::Term( Soprano::Vocabulary::RDF::type(),
00069                                                                Soprano::Vocabulary::Xesam::Music() ) );
00070 
00071     // today's files
00072     Search::Term term;
00073     QDateTime today( QDate::currentDate(), QTime(), Qt::UTC );
00074     term.setType( Search::Term::AndTerm );
00075     term.addSubTerm( Search::Term( Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::Xesam::File() ) );
00076     term.addSubTerm( Search::Term( Soprano::Vocabulary::Xesam::sourceModified(), today, Search::Term::GreaterOrEqual ) );
00077     addDefaultSearch( i18n( "Today's Files" ), term );
00078 
00079     // yesterday's files
00080     term = Search::Term();
00081     term.setType( Search::Term::AndTerm );
00082     term.addSubTerm( Search::Term( Soprano::Vocabulary::RDF::type(), Soprano::Vocabulary::Xesam::File() ) );
00083     QDateTime yesterday( today );
00084     yesterday.addDays( -1 );
00085     term.addSubTerm( Search::Term( Soprano::Vocabulary::Xesam::sourceModified(), yesterday, Search::Term::GreaterOrEqual ) );
00086     term.addSubTerm( Search::Term( Soprano::Vocabulary::Xesam::sourceModified(), today, Search::Term::Smaller ) );
00087     addDefaultSearch( i18n( "Yesterday's Files" ), term );
00088 
00089     // select the 10 most recent files:
00090     addDefaultSearch( i18n( "Recent Files" ),
00091                       Search::Query( "select distinct ?r where { "
00092                                      "?r a <http://freedesktop.org/standards/xesam/1.0/core#File> . ?r "
00093                                      "<http://freedesktop.org/standards/xesam/1.0/core#sourceModified> ?date . "
00094                                      "} ORDER BY DESC(?date) LIMIT 10" ) );
00095 }
00096 
00097 
00098 Nepomuk::SearchProtocol::~SearchProtocol()
00099 {
00100 }
00101 
00102 
00103 void Nepomuk::SearchProtocol::addDefaultSearch( const QString& name, const Search::Query& q )
00104 {
00105     Search::Query query( q );
00106     query.addRequestProperty( Soprano::Vocabulary::Xesam::url(), true );
00107     m_defaultSearches.insert( name, query );
00108 }
00109 
00110 
00111 Nepomuk::SearchFolder* Nepomuk::SearchProtocol::extractSearchFolder( const KUrl& url )
00112 {
00113     QString name = url.path().section( '/', 0, 0, QString::SectionSkipEmpty );
00114     kDebug() << url << name;
00115     if ( SearchFolder* sf = getDefaultQueryFolder( name ) ) {
00116         kDebug() << "-----> is default search folder";
00117         return sf;
00118     }
00119     else if ( SearchFolder* sf = getQueryResults( name ) ) {
00120         kDebug() << "-----> is on-the-fly search folder";
00121         return sf;
00122     }
00123     else {
00124         kDebug() << "-----> does not exist.";
00125         return 0;
00126     }
00127 }
00128 
00129 
00130 void Nepomuk::SearchProtocol::listDir( const KUrl& url )
00131 {
00132     kDebug() << url;
00133 
00134     //
00135     // Root dir: * list default searches: "all music files", "recent files"
00136     //           * list configuration entries: "create new default search"
00137     //
00138     // Root dir with query:
00139     //           * execute the query (cached) and list its results
00140     //
00141     // some folder:
00142     //           * Look for a default search and execute that
00143     //
00144 
00145     if ( url.path() == "/" ) {
00146         listRoot();
00147     }
00148     else if ( url.directory() == "/" &&
00149               m_defaultSearches.contains( url.fileName() ) ) {
00150         // the default search name is the folder name
00151         listDefaultSearch( url.fileName() );
00152     }
00153     else {
00154         // lets create an on-the-fly search
00155         listQuery( url.fileName() );
00156     }
00157 }
00158 
00159 
00160 void Nepomuk::SearchProtocol::get( const KUrl& url )
00161 {
00162     kDebug() << url;
00163     ForwardingSlaveBase::get( url );
00164 }
00165 
00166 
00167 void Nepomuk::SearchProtocol::put( const KUrl& url, int permissions, KIO::JobFlags flags )
00168 {
00169     kDebug() << url << permissions << flags;
00170     // this will work only for existing files (ie. overwrite to allow saving of opened files)
00171     ForwardingSlaveBase::put( url, permissions, flags );
00172 }
00173 
00174 
00175 void Nepomuk::SearchProtocol::mimetype( const KUrl& url )
00176 {
00177     kDebug() << url;
00178 
00179     if ( url.path() == "/" ) {
00180         mimeType( QString::fromLatin1( "inode/directory" ) );
00181         finished();
00182     }
00183     else if ( url.directory() == "/" &&
00184               m_defaultSearches.contains( url.fileName() ) ) {
00185         mimeType( QString::fromLatin1( "inode/directory" ) );
00186         finished();
00187     }
00188     else {
00189         ForwardingSlaveBase::mimetype( url );
00190     }
00191 }
00192 
00193 
00194 void Nepomuk::SearchProtocol::stat( const KUrl& url )
00195 {
00196     kDebug() << url;
00197 
00198     if ( url.path() == "/" ) {
00199         if ( url.queryItems().isEmpty() ) {
00200             kDebug() << "/";
00201             //
00202             // stat the root path
00203             //
00204             KIO::UDSEntry uds;
00205             uds.insert( KIO::UDSEntry::UDS_NAME, QString::fromLatin1( "/" ) );
00206             uds.insert( KIO::UDSEntry::UDS_ICON_NAME, QString::fromLatin1( "nepomuk" ) );
00207             uds.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR );
00208             uds.insert( KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1( "inode/directory" ) );
00209 
00210             statEntry( uds );
00211             finished();
00212         }
00213         else {
00214             kDebug() << "query folder:" << url.queryItemValue("query");
00215 
00216             //
00217             // stat a query folder
00218             //
00219             KIO::UDSEntry uds;
00220             uds.insert( KIO::UDSEntry::UDS_NAME, url.fileName() );
00221             uds.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR );
00222             uds.insert( KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1( "inode/directory" ) );
00223 
00224             statEntry( uds );
00225             finished();
00226         }
00227     }
00228     else if ( url.directory() == "/" ) {
00229         if ( SearchFolder* sf = extractSearchFolder( url ) ) {
00230             KIO::UDSEntry uds = statDefaultSearchFolder( sf->name() );
00231             Q_ASSERT( !uds.stringValue( KIO::UDSEntry::UDS_NAME ).isEmpty() );
00232             statEntry( uds );
00233             finished();
00234         }
00235         else {
00236             error( KIO::ERR_DOES_NOT_EXIST, url.url() );
00237         }
00238     }
00239     else if ( SearchFolder* folder = extractSearchFolder( url ) ) {
00240         folder->stat( url.fileName() );
00241     }
00242     else {
00243         error( KIO::ERR_DOES_NOT_EXIST, url.url() );
00244     }
00245 }
00246 
00247 
00248 bool Nepomuk::SearchProtocol::rewriteUrl( const KUrl& url, KUrl& newURL )
00249 {
00250     kDebug() << url << newURL;
00251 
00252     if ( SearchFolder* folder = extractSearchFolder( url ) ) {
00253         if ( SearchEntry* entry = folder->findEntry( url.fileName() ) ) {
00254             QString localPath = entry->entry().stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
00255             if ( localPath.isEmpty() ) {
00256                 newURL = localPath;
00257             }
00258             else {
00259                 newURL = entry->resource();
00260             }
00261             return true;
00262         }
00263     }
00264 
00265     return false;
00266 }
00267 
00268 
00269 void Nepomuk::SearchProtocol::listRoot()
00270 {
00271     kDebug();
00272 
00273     listDefaultSearches();
00274     listActions();
00275 
00276     listEntry( KIO::UDSEntry(), true );
00277     finished();
00278 }
00279 
00280 
00281 void Nepomuk::SearchProtocol::listActions()
00282 {
00283     // FIXME: manage default searches
00284 }
00285 
00286 
00287 Nepomuk::SearchFolder* Nepomuk::SearchProtocol::getQueryResults( const QString& query )
00288 {
00289     if ( m_searchCache.contains( query ) ) {
00290         return m_searchCache[query];
00291     }
00292     else {
00293         if ( m_searchCache.count() >= SEARCH_CACHE_MAX ) {
00294             QString oldestQuery = m_searchCacheNameQueue.dequeue();
00295             delete m_searchCache.take( oldestQuery );
00296         }
00297 
00298         Search::Query q = Nepomuk::Search::QueryParser::parseQuery( query );
00299         q.addRequestProperty( Soprano::Vocabulary::Xesam::url(), true );
00300         SearchFolder* folder = new SearchFolder( query, q, this );
00301         m_searchCacheNameQueue.enqueue( query );
00302         m_searchCache.insert( query, folder );
00303         return folder;
00304     }
00305 }
00306 
00307 
00308 Nepomuk::SearchFolder* Nepomuk::SearchProtocol::getDefaultQueryFolder( const QString& name )
00309 {
00310     if ( m_defaultSearchCache.contains( name ) ) {
00311         return m_defaultSearchCache[name];
00312     }
00313     else if ( m_defaultSearches.contains( name ) ) {
00314         SearchFolder* folder = new SearchFolder( name, m_defaultSearches[name], this );
00315         m_defaultSearchCache.insert( name, folder );
00316         return folder;
00317     }
00318     else {
00319         return 0;
00320     }
00321 }
00322 
00323 
00324 void Nepomuk::SearchProtocol::listQuery( const QString& query )
00325 {
00326     kDebug() << query;
00327     getQueryResults( query )->list();
00328 }
00329 
00330 
00331 void Nepomuk::SearchProtocol::listDefaultSearches()
00332 {
00333     for ( QHash<QString, Nepomuk::Search::Query>::const_iterator it = m_defaultSearches.constBegin();
00334           it != m_defaultSearches.constEnd(); ++it ) {
00335         listEntry( statDefaultSearchFolder( it.key() ), false );
00336     }
00337 }
00338 
00339 
00340 void Nepomuk::SearchProtocol::listDefaultSearch( const QString& name )
00341 {
00342     kDebug() << name;
00343     if ( m_defaultSearches.contains( name ) ) {
00344         getDefaultQueryFolder( name )->list();
00345     }
00346     else {
00347         error( KIO::ERR_CANNOT_ENTER_DIRECTORY, "Unknown default search: " + name );
00348         finished();
00349     }
00350 }
00351 
00352 extern "C"
00353 {
00354     KDE_EXPORT int kdemain( int argc, char **argv )
00355     {
00356         // necessary to use other kio slaves
00357         KComponentData( "kio_nepomuksearch" );
00358         QCoreApplication app( argc, argv );
00359 
00360         if ( Nepomuk::ResourceManager::instance()->init() ) {
00361             kError() << "Unable to initialized Nepomuk.";
00362             return -1;
00363         }
00364 
00365         kDebug(7102) << "Starting nepomuksearch slave " << getpid();
00366 
00367         Nepomuk::SearchProtocol slave( argv[2], argv[3] );
00368         slave.dispatchLoop();
00369 
00370         kDebug(7102) << "Nepomuksearch slave Done";
00371 
00372         return 0;
00373     }
00374 }
00375 
00376 #include "kio_nepomuksearch.moc"

NepomukDaemons

Skip menu "NepomukDaemons"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KCMShell
  • KNotify
  • KStyles
  • Nepomuk Daemons
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal