• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Nepomuk-Core

  • sources
  • kde-4.12
  • kdelibs
  • nepomuk-core
  • services
  • fileindexer
fileindexerconfig.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE Project
2  Copyright (c) 2008-2010 Sebastian Trueg <trueg@kde.org>
3  Copyright (c) 2013 Vishesh Handa <me@vhanda.in>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "fileindexerconfig.h"
21 #include "fileexcludefilters.h"
22 
23 #include <QtCore/QStringList>
24 #include <QtCore/QDir>
25 #include <QWriteLocker>
26 #include <QReadLocker>
27 
28 #include <KDirWatch>
29 #include <KStandardDirs>
30 #include <KConfigGroup>
31 #include <KDebug>
32 
33 
34 namespace {
36  bool isDirHidden( QDir& dir ) {
37  if ( QFileInfo( dir.path() ).isHidden() )
38  return true;
39  else if ( dir.cdUp() )
40  return isDirHidden( dir );
41  else
42  return false;
43  }
44 
45  bool isDirHidden(const QString& path) {
46 #ifdef Q_OS_WIN
47  QDir dir(path);
48  return isDirHidden(dir);
49 #else
50  return path.contains( QLatin1String("/.") );
51 #endif
52  }
53 }
54 
55 Nepomuk2::FileIndexerConfig* Nepomuk2::FileIndexerConfig::s_self = 0;
56 
57 Nepomuk2::FileIndexerConfig::FileIndexerConfig(QObject* parent)
58  : QObject(parent)
59  , m_config( "nepomukstrigirc" )
60  , m_indexHidden(false)
61 {
62  if(!s_self) {
63  s_self = this;
64  }
65 
66  KDirWatch* dirWatch = KDirWatch::self();
67  connect( dirWatch, SIGNAL( dirty( const QString& ) ),
68  this, SLOT( slotConfigDirty() ) );
69  connect( dirWatch, SIGNAL( created( const QString& ) ),
70  this, SLOT( slotConfigDirty() ) );
71  dirWatch->addFile( KStandardDirs::locateLocal( "config", m_config.name() ) );
72 
73  forceConfigUpdate();
74 }
75 
76 
77 Nepomuk2::FileIndexerConfig::~FileIndexerConfig()
78 {
79 }
80 
81 
82 Nepomuk2::FileIndexerConfig* Nepomuk2::FileIndexerConfig::self()
83 {
84  return s_self;
85 }
86 
87 
88 QList<QPair<QString, bool> > Nepomuk2::FileIndexerConfig::folders() const
89 {
90  return m_folderCache;
91 }
92 
93 
94 QStringList Nepomuk2::FileIndexerConfig::includeFolders() const
95 {
96  QStringList fl;
97  for ( int i = 0; i < m_folderCache.count(); ++i ) {
98  if ( m_folderCache[i].second )
99  fl << m_folderCache[i].first;
100  }
101  return fl;
102 }
103 
104 
105 QStringList Nepomuk2::FileIndexerConfig::excludeFolders() const
106 {
107  QStringList fl;
108  for ( int i = 0; i < m_folderCache.count(); ++i ) {
109  if ( !m_folderCache[i].second )
110  fl << m_folderCache[i].first;
111  }
112  return fl;
113 }
114 
115 
116 QStringList Nepomuk2::FileIndexerConfig::excludeFilters() const
117 {
118  KConfigGroup cfg = m_config.group( "General" );
119 
120  // read configured exclude filters
121  QSet<QString> filters = cfg.readEntry( "exclude filters", defaultExcludeFilterList() ).toSet();
122 
123  // make sure we always keep the latest default exclude filters
124  // TODO: there is one problem here. What if the user removed some of the default filters?
125  if(cfg.readEntry("exclude filters version", 0) < defaultExcludeFilterListVersion()) {
126  filters += defaultExcludeFilterList().toSet();
127 
128  // write the config directly since the KCM does not have support for the version yet
129  // TODO: make this class public and use it in the KCM
130  cfg.writeEntry("exclude filters", QStringList::fromSet(filters));
131  cfg.writeEntry("exclude filters version", defaultExcludeFilterListVersion());
132  }
133 
134  // remove duplicates
135  return QStringList::fromSet(filters);
136 }
137 
138 
139 bool Nepomuk2::FileIndexerConfig::indexHiddenFilesAndFolders() const
140 {
141  return m_indexHidden;
142 }
143 
144 
145 KIO::filesize_t Nepomuk2::FileIndexerConfig::minDiskSpace() const
146 {
147  // default: 200 MB
148  return m_config.group( "General" ).readEntry( "min disk space", KIO::filesize_t( 200*1024*1024 ) );
149 }
150 
151 
152 void Nepomuk2::FileIndexerConfig::slotConfigDirty()
153 {
154  if( forceConfigUpdate() )
155  emit configChanged();
156 }
157 
158 
159 bool Nepomuk2::FileIndexerConfig::isInitialRun() const
160 {
161  return m_config.group( "General" ).readEntry( "first run", true );
162 }
163 
164 
165 bool Nepomuk2::FileIndexerConfig::shouldBeIndexed( const QString& path ) const
166 {
167  QFileInfo fi( path );
168  if( fi.isDir() ) {
169  return shouldFolderBeIndexed( path );
170  }
171  else {
172  return( shouldFolderBeIndexed( fi.absolutePath() ) &&
173  ( !fi.isHidden() || indexHiddenFilesAndFolders() ) &&
174  shouldFileBeIndexed( fi.fileName() ) );
175  }
176 }
177 
178 
179 bool Nepomuk2::FileIndexerConfig::shouldFolderBeIndexed( const QString& path ) const
180 {
181  QString folder;
182  if ( folderInFolderList( path, folder ) ) {
183  // we always index the folders in the list
184  // ignoring the name filters
185  if ( folder == path )
186  return true;
187 
188  // check for hidden folders
189  QDir dir( path );
190  if ( !indexHiddenFilesAndFolders() && isDirHidden( dir ) )
191  return false;
192 
193  // reset dir, cause isDirHidden modifies the QDir
194  dir = path;
195 
196  // check the exclude filters for all components of the path
197  // after folder
198  const QStringList pathComponents = path.mid(folder.count()).split('/', QString::SkipEmptyParts);
199  foreach(const QString& c, pathComponents) {
200  if(!shouldFileBeIndexed( c )) {
201  return false;
202  }
203  }
204  return true;
205  }
206  else {
207  return false;
208  }
209 }
210 
211 
212 bool Nepomuk2::FileIndexerConfig::shouldFileBeIndexed( const QString& fileName ) const
213 {
214  // check the filters
215  QWriteLocker lock( &m_folderCacheMutex );
216  return !m_excludeFilterRegExpCache.exactMatch( fileName );
217 }
218 
219 bool Nepomuk2::FileIndexerConfig::shouldMimeTypeBeIndexed(const QString& mimeType) const
220 {
221  QReadLocker lock( &m_mimetypeMutex );
222  return !m_excludeMimetypes.contains( mimeType );
223 }
224 
225 
226 bool Nepomuk2::FileIndexerConfig::folderInFolderList(const QString& path)
227 {
228  QString str;
229  return folderInFolderList( path, str );
230 }
231 
232 bool Nepomuk2::FileIndexerConfig::folderInFolderList( const QString& path, QString& folder ) const
233 {
234  QReadLocker lock( &m_folderCacheMutex );
235 
236  const QString p = KUrl( path ).path( KUrl::RemoveTrailingSlash );
237 
238  // we traverse the list backwards to catch all exclude folders
239  int i = m_folderCache.count();
240  while ( --i >= 0 ) {
241  const QString& f = m_folderCache[i].first;
242  const bool include = m_folderCache[i].second;
243  if ( p.startsWith( f ) ) {
244  folder = f;
245  return include;
246  }
247  }
248  // path is not in the list, thus it should not be included
249  folder.clear();
250  return false;
251 }
252 
253 
254 namespace {
259  bool alreadyExcluded( const QList<QPair<QString, bool> >& folders, const QString& f )
260  {
261  bool included = false;
262  for ( int i = 0; i < folders.count(); ++i ) {
263  if ( f != folders[i].first &&
264  f.startsWith( KUrl( folders[i].first ).path( KUrl::AddTrailingSlash ) ) ) {
265  included = folders[i].second;
266  }
267  }
268  return !included;
269  }
270 
274  void insertSortFolders( const QStringList& folders, bool include, QList<QPair<QString, bool> >& result )
275  {
276  foreach( const QString& f, folders ) {
277  int pos = 0;
278  QString path = KUrl( f ).path( KUrl::RemoveTrailingSlash );
279  while ( result.count() > pos &&
280  result[pos].first < path )
281  ++pos;
282  result.insert( pos, qMakePair( path, include ) );
283  }
284  }
285 
291  void cleanupList( QList<QPair<QString, bool> >& result )
292  {
293  int i = 0;
294  while ( i < result.count() ) {
295  if ( result[i].first.isEmpty() ||
296  (!result[i].second &&
297  alreadyExcluded( result, result[i].first ) ))
298  result.removeAt( i );
299  else
300  ++i;
301  }
302  }
303 }
304 
305 
306 void Nepomuk2::FileIndexerConfig::fillIncludeFolderChanges(const Nepomuk2::FileIndexerConfig::Entry& entry, const QSet<QString>& include, QStringList* includeAdded, QStringList* includeRemoved)
307 {
308  QStringList added = QSet<QString>(include).subtract( entry.includes ).toList();
309  QStringList removed = QSet<QString>(entry.includes).subtract( include ).toList();
310 
311  if( includeAdded )
312  includeAdded->append( added );
313 
314  if( includeRemoved )
315  includeRemoved->append( removed );
316 }
317 
318 void Nepomuk2::FileIndexerConfig::fillExcludeFolderChanges(const Nepomuk2::FileIndexerConfig::Entry& entry, const QSet<QString>& exclude, QStringList* excludeAdded, QStringList* excludeRemoved)
319 {
320  QStringList added = QSet<QString>(exclude).subtract( entry.excludes ).toList();
321  QStringList removed = QSet<QString>(entry.excludes).subtract( exclude ).toList();
322 
323  if( excludeAdded )
324  excludeAdded->append( added );
325 
326  if( excludeRemoved )
327  excludeRemoved->append( removed );
328 }
329 
330 
331 bool Nepomuk2::FileIndexerConfig::buildFolderCache()
332 {
333  QWriteLocker lock( &m_folderCacheMutex );
334 
335  //
336  // General folders
337  //
338  KConfigGroup group = m_config.group( "General" );
339  QStringList includeFoldersPlain = group.readPathEntry( "folders", QStringList() << QDir::homePath() );
340  QStringList excludeFoldersPlain = group.readPathEntry( "exclude folders", QStringList() );
341 
342  m_folderCache.clear();
343  insertSortFolders( includeFoldersPlain, true, m_folderCache );
344  insertSortFolders( excludeFoldersPlain, false, m_folderCache );
345 
346  QStringList includeAdded;
347  QStringList includeRemoved;
348  QStringList excludeAdded;
349  QStringList excludeRemoved;;
350 
351  QSet<QString> includeSet = includeFoldersPlain.toSet();
352  QSet<QString> excludeSet = excludeFoldersPlain.toSet();
353 
354  Entry& generalEntry = m_entries[ "General" ];
355  fillIncludeFolderChanges( generalEntry, includeSet, &includeAdded, &includeRemoved );
356  fillExcludeFolderChanges( generalEntry, excludeSet, &excludeAdded, &excludeRemoved );
357 
358  generalEntry.includes = includeSet;
359  generalEntry.excludes = excludeSet;
360 
361  //
362  // Removable Media
363  //
364  QStringList groupList = m_config.groupList();
365  foreach( const QString& groupName, groupList ) {
366  if( !groupName.startsWith("Device-") )
367  continue;
368 
369  KConfigGroup group = m_config.group( groupName );
370  QString mountPath = group.readEntry( "mount path", QString() );
371  if( mountPath.isEmpty() )
372  continue;
373 
374  QStringList includes = group.readPathEntry( "folders", QStringList() );
375  QStringList excludes = group.readPathEntry( "exclude folders", QStringList() );
376 
377  QStringList includeFoldersPlain;
378  foreach( const QString& path, includes )
379  includeFoldersPlain << mountPath + path;
380 
381  QStringList excludeFoldersPlain;
382  foreach( const QString& path, excludes )
383  excludeFoldersPlain << mountPath + path;
384 
385  insertSortFolders( includeFoldersPlain, true, m_folderCache );
386  insertSortFolders( excludeFoldersPlain, false, m_folderCache );
387 
388  QSet<QString> includeSet = includeFoldersPlain.toSet();
389  QSet<QString> excludeSet = excludeFoldersPlain.toSet();
390 
391  Entry& cacheEntry = m_entries[ groupName ];
392  fillIncludeFolderChanges( cacheEntry, includeSet, &includeAdded, &includeRemoved );
393  fillExcludeFolderChanges( cacheEntry, excludeSet, &excludeAdded, &excludeRemoved );
394 
395  cacheEntry.includes = includeSet;
396  cacheEntry.excludes = excludeSet;
397  }
398 
399  cleanupList( m_folderCache );
400 
401  bool changed = false;
402  if( !includeAdded.isEmpty() || !includeRemoved.isEmpty() ) {
403  emit includeFolderListChanged( includeAdded, includeRemoved );
404  changed = true;
405  }
406 
407  if( !excludeAdded.isEmpty() || !excludeRemoved.isEmpty() ) {
408  emit excludeFolderListChanged( excludeAdded, excludeRemoved );
409  changed = true;
410  }
411 
412  return changed;
413 }
414 
415 
416 bool Nepomuk2::FileIndexerConfig::buildExcludeFilterRegExpCache()
417 {
418  QWriteLocker lock( &m_folderCacheMutex );
419  QStringList newFilters = excludeFilters();
420  m_excludeFilterRegExpCache.rebuildCacheFromFilterList( newFilters );
421 
422  QSet<QString> newFilterSet = newFilters.toSet();
423  if( m_prevFileFilters != newFilterSet ) {
424  m_prevFileFilters = newFilterSet;
425  emit fileExcludeFiltersChanged();
426  return true;
427  }
428 
429  return false;
430 }
431 
432 bool Nepomuk2::FileIndexerConfig::buildMimeTypeCache()
433 {
434  QWriteLocker lock( &m_mimetypeMutex );
435  QStringList newMimeExcludes = m_config.group( "General" ).readPathEntry( "exclude mimetypes", QStringList() );
436 
437  QSet<QString> newMimeExcludeSet = newMimeExcludes.toSet();
438  if( m_excludeMimetypes != newMimeExcludeSet ) {
439  m_excludeMimetypes = newMimeExcludeSet;
440  emit mimeTypeFiltersChanged();
441  return true;
442  }
443 
444  return false;
445 }
446 
447 
448 bool Nepomuk2::FileIndexerConfig::forceConfigUpdate()
449 {
450  m_config.reparseConfiguration();
451  bool changed = false;
452 
453  changed = buildFolderCache() || changed;
454  changed = buildExcludeFilterRegExpCache() || changed;
455  changed = buildMimeTypeCache() || changed;
456 
457  bool hidden = m_config.group( "General" ).readEntry( "index hidden folders", false );
458  if( hidden != m_indexHidden ) {
459  m_indexHidden = hidden;
460  changed = true;
461  }
462 
463  return changed;
464 }
465 
466 void Nepomuk2::FileIndexerConfig::setInitialRun(bool isInitialRun)
467 {
468  m_config.group( "General" ).writeEntry( "first run", isInitialRun );
469 }
470 
471 bool Nepomuk2::FileIndexerConfig::initialUpdateDisabled() const
472 {
473  return m_config.group( "General" ).readEntry( "disable initial update", true );
474 }
475 
476 bool Nepomuk2::FileIndexerConfig::suspendOnPowerSaveDisabled() const
477 {
478  return m_config.group( "General" ).readEntry( "disable suspend on powersave", false );
479 }
480 
481 bool Nepomuk2::FileIndexerConfig::isDebugModeEnabled() const
482 {
483  return m_config.group( "General" ).readEntry( "debug mode", false );
484 }
485 
486 
487 #include "fileindexerconfig.moc"
fileindexerconfig.h
Nepomuk2::FileIndexerConfig::shouldFolderBeIndexed
bool shouldFolderBeIndexed(const QString &path) const
Check if the folder at path should be indexed.
Definition: fileindexerconfig.cpp:179
Nepomuk2::FileIndexerConfig::shouldMimeTypeBeIndexed
bool shouldMimeTypeBeIndexed(const QString &mimeType) const
Checks if mimeType should be indexed.
Definition: fileindexerconfig.cpp:219
Nepomuk2::FileIndexerConfig::excludeFilters
QStringList excludeFilters() const
Definition: fileindexerconfig.cpp:116
Nepomuk2::FileIndexerConfig::FileIndexerConfig
FileIndexerConfig(QObject *parent=0)
Create a new file indexr config.
Definition: fileindexerconfig.cpp:57
Nepomuk2::defaultExcludeFilterListVersion
NEPOMUKCOMMON_EXPORT int defaultExcludeFilterListVersion()
Definition: fileexcludefilters.cpp:113
Nepomuk2::FileIndexerConfig::isDebugModeEnabled
bool isDebugModeEnabled() const
Check if the debug mode is enabled.
Definition: fileindexerconfig.cpp:481
Nepomuk2::FileIndexerConfig::includeFolders
QStringList includeFolders() const
The folders to search for files to analyze.
Definition: fileindexerconfig.cpp:94
Nepomuk2::FileIndexerConfig
Active config class which emits signals if the config was changed, for example if the KCM saved the c...
Definition: fileindexerconfig.h:38
QObject
Nepomuk2::FileIndexerConfig::folderInFolderList
bool folderInFolderList(const QString &path)
Returns true if the folder is in the list indexed directories and not in the list of exclude director...
Definition: fileindexerconfig.cpp:226
Nepomuk2::FileIndexerConfig::shouldFileBeIndexed
bool shouldFileBeIndexed(const QString &fileName) const
Check fileName for all exclude filters.
Definition: fileindexerconfig.cpp:212
Nepomuk2::FileIndexerConfig::excludeFolders
QStringList excludeFolders() const
The folders that should be excluded.
Definition: fileindexerconfig.cpp:105
Nepomuk2::FileIndexerConfig::shouldBeIndexed
bool shouldBeIndexed(const QString &path) const
Check if path should be indexed taking into account the includeFolders(), the excludeFolders(), and the excludeFilters().
Definition: fileindexerconfig.cpp:165
Nepomuk2::FileIndexerConfig::folders
QList< QPair< QString, bool > > folders() const
A cleaned up list of all include and exclude folders with their respective include/exclude flag sorte...
Definition: fileindexerconfig.cpp:88
Nepomuk2::FileIndexerConfig::indexHiddenFilesAndFolders
bool indexHiddenFilesAndFolders() const
Definition: fileindexerconfig.cpp:139
Nepomuk2::FileIndexerConfig::minDiskSpace
KIO::filesize_t minDiskSpace() const
The minimal available disk space.
Definition: fileindexerconfig.cpp:145
fileexcludefilters.h
Nepomuk2::FileIndexerConfig::initialUpdateDisabled
bool initialUpdateDisabled() const
A "hidden" config option which allows to disable the initial update of all indexed folders...
Definition: fileindexerconfig.cpp:471
Nepomuk2::defaultExcludeFilterList
NEPOMUKCOMMON_EXPORT QStringList defaultExcludeFilterList()
Definition: fileexcludefilters.cpp:103
Nepomuk2::FileIndexerConfig::~FileIndexerConfig
~FileIndexerConfig()
Definition: fileindexerconfig.cpp:77
Nepomuk2::FileIndexerConfig::isInitialRun
bool isInitialRun() const
true the first time the service is run (or after manually tampering with the config.
Definition: fileindexerconfig.cpp:159
Nepomuk2::FileIndexerConfig::setInitialRun
void setInitialRun(bool isInitialRun)
Should be called once the initial indexing is done, ie.
Definition: fileindexerconfig.cpp:466
Nepomuk2::FileIndexerConfig::self
static FileIndexerConfig * self()
Get the first created instance of FileIndexerConfig.
Definition: fileindexerconfig.cpp:82
Nepomuk2::FileIndexerConfig::suspendOnPowerSaveDisabled
bool suspendOnPowerSaveDisabled() const
A "hidden" config option which allows to disable the feature where the file indexing is suspended whe...
Definition: fileindexerconfig.cpp:476
Nepomuk2::FileIndexerConfig::forceConfigUpdate
bool forceConfigUpdate()
Reread the config from disk and update the configuration cache.
Definition: fileindexerconfig.cpp:448
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Nepomuk-Core

Skip menu "Nepomuk-Core"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal