Example #1
0
void
CollectionScanner::doJob() //SLOT
{
    std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
    std::cout << "<scanner>";


    QStringList entries;

    if( m_restart ) {
        QFile logFile( m_logfile );
        logFile.open( IO_ReadOnly );
        QString lastFile = logFile.readAll();

        QFile folderFile( amaroK::saveLocation( QString::null ) + "collection_scan.files"   );
        folderFile.open( IO_ReadOnly );
        entries = QStringList::split( "\n", folderFile.readAll() );

        for( int count = entries.findIndex( lastFile ) + 1; count; --count )
            entries.pop_front();

//         debug() << "Restarting at: " << entries.front() << endl;
    }
    else {
        foreachType( QStringList, m_folders ) {
            if( (*it).isEmpty() )
                //apparently somewhere empty strings get into the mix
                //which results in a full-system scan! Which we can't allow
                continue;

            QString dir = *it;
            if( !dir.endsWith( "/" ) )
                dir += '/';

            readDir( dir, entries );
        }

        QFile folderFile( amaroK::saveLocation( QString::null ) + "collection_scan.files"   );
        folderFile.open( IO_WriteOnly );
        QTextStream stream( &folderFile );
        stream << entries.join( "\n" );
        folderFile.close();
    }

    if( !entries.isEmpty() ) {
        if( !m_restart ) {
            AttributeMap attributes;
            attributes["count"] = QString::number( entries.count() );
            writeElement( "itemcount", attributes );
        }

        scanFiles( entries );
    }

    std::cout << "</scanner>" << std::endl;

    quit();
}
FileProvider::FileProvider( const std::string &root )
{
	scanFiles( root, _files );
	printf( "[FileProvider] Scan files: %d\n", _files.size() );
	
	_scan = 0;
	_exit = false;
	_loop = true;
}
Example #3
0
bool FileSystemWatcher::watch(const Path &p)
{
    Path path = p;
    assert(!path.isEmpty());
    std::lock_guard<std::mutex> lock(mMutex);
    const Path::Type type = path.type();
    uint32_t flags = 0;
    switch (type) {
    case Path::File:
        path = path.parentDir();
        // fall through
    case Path::Directory:
        flags = NOTE_RENAME|NOTE_DELETE|NOTE_EXTEND|NOTE_WRITE|NOTE_ATTRIB|NOTE_REVOKE;
        break;
    default:
        error("FileSystemWatcher::watch() '%s' doesn't seem to be watchable", path.constData());
        return false;
    }

    if (!path.endsWith('/'))
        path += '/';

    if (isWatching(path))
        return false;

    int ret = ::open(path.nullTerminated(), O_RDONLY);
    //static int cnt = 0;
    //printf("wanting to watch [%05d] %s : %d\n", ++cnt, path.nullTerminated(), ret);
    if (ret != -1) {
        struct kevent change;
        struct timespec nullts = { 0, 0 };
        EV_SET(&change, ret, EVFILT_VNODE, EV_ADD|EV_ENABLE|EV_CLEAR, flags, 0, 0);
        if (::kevent(mFd, &change, 1, 0, 0, &nullts) == -1) {
            // bad things have happened
            error("FileSystemWatcher::watch() kevent failed for '%s' (%d) %s",
                  path.constData(), errno, Rct::strerror().constData());
            ::close(ret);
            return false;
        }
    }
    if (ret == -1) {
        error("FileSystemWatcher::watch() watch failed for '%s' (%d) %s",
              path.constData(), errno, Rct::strerror().constData());
        return false;
    }

    mWatchedByPath[path] = ret;
    mWatchedById[ret] = path;

    FSUserData data;
    data.watcher = this;
    path.visit([&data](const Path &p) {
            return scanFiles(p, &data);
            });

    return true;
}
Example #4
0
uint8_t SFX::setFont(uint8_t font)
{
  //Serial.print("setFont "); Serial.println(font);
  if (m_numFonts) {
    if (font != m_currentFont) {
      m_currentFont = font % m_numFonts;
      scanFiles(m_currentFont);
    }
  }
  else {
    m_currentFont = 0;
  }
  return m_currentFont;
}
void FileProvider::scanFiles( const std::string &root, std::vector<std::string> &files ) {
	if (fs::exists( root )) {
		fs::directory_iterator end_itr;
		for (fs::directory_iterator itr( root ); itr != end_itr; ++itr) {
			if (fs::is_directory( itr->status() )) {
				scanFiles( itr->path().string(), files );
			}
			else if (fs::is_regular_file( itr->status() )) {
				fs::path file = itr->path();
				if (file.extension() == ".ts") {
					files.push_back( file.string() );
				}
			}
		}
	}
}
MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
{
    ListviewDelegate *delegate = new ListviewDelegate();
    model = new QStandardItemModel();
    this->setWindowFlags(Qt::FramelessWindowHint);
    ui->setupUi(this);
    ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->listView->setItemDelegate(delegate);
    ui->listView->setModel(model);
    scanFiles("/mnt/udisk");
    on_allSongs_clicked();
    currentSongIndex = -1;
    connect(&controller, SIGNAL(TimeChanged(QString,int)), this, SLOT(timeChanged(QString,int)));
    connect(&controller, SIGNAL(StatusChanged(bool)), this, SLOT(statusChanged(bool)));
    connect(&controller, SIGNAL(Finished()), this, SLOT(onFinished()));
}
Example #7
0
inline Error scanFiles(const FileInfo& fromRoot,
                       const FileScannerOptions& options,
                       tree<FileInfo>* pTree)
{
   return scanFiles(pTree->set_head(fromRoot), options, pTree);
}
Example #8
0
// register a new file monitor
Handle registerMonitor(const FilePath& filePath,
                       bool recursive,
                       const boost::function<bool(const FileInfo&)>& filter,
                       const Callbacks& callbacks)
{
   // allocate file path
   CFStringRef filePathRef = ::CFStringCreateWithCString(
                                       kCFAllocatorDefault,
                                       filePath.absolutePath().c_str(),
                                       kCFStringEncodingUTF8);
   if (filePathRef == NULL)
   {
      callbacks.onRegistrationError(systemError(
                                       boost::system::errc::not_enough_memory,
                                       ERROR_LOCATION));
      return Handle();
   }
   CFRefScope filePathRefScope(filePathRef);

   // allocate paths array
   CFArrayRef pathsArrayRef = ::CFArrayCreate(kCFAllocatorDefault,
                                              (const void **)&filePathRef,
                                              1,
                                              NULL);
   if (pathsArrayRef == NULL)
   {
      callbacks.onRegistrationError(systemError(
                                       boost::system::errc::not_enough_memory,
                                       ERROR_LOCATION));
      return Handle();
   }
   CFRefScope pathsArrayRefScope(pathsArrayRef);


   // create and allocate FileEventContext (create auto-ptr in case we
   // return early, we'll call release later before returning)
   FileEventContext* pContext = new FileEventContext();
   pContext->rootPath = filePath;
   pContext->recursive = recursive;
   pContext->filter = filter;
   std::auto_ptr<FileEventContext> autoPtrContext(pContext);
   FSEventStreamContext context;
   context.version = 0;
   context.info = (void*) pContext;
   context.retain = NULL;
   context.release = NULL;
   context.copyDescription = NULL;

   // create the stream and save a reference to it
   pContext->streamRef = ::FSEventStreamCreate(
                  kCFAllocatorDefault,
                  &fileEventCallback,
                  &context,
                  pathsArrayRef,
                  kFSEventStreamEventIdSinceNow,
                  1,
                  kFSEventStreamCreateFlagNoDefer |
                  kFSEventStreamCreateFlagWatchRoot);
   if (pContext->streamRef == NULL)
   {
      callbacks.onRegistrationError(systemError(
                                       boost::system::errc::no_stream_resources,
                                       ERROR_LOCATION));
      return Handle();
   }

   // schedule with the run loop
   ::FSEventStreamScheduleWithRunLoop(pContext->streamRef,
                                      ::CFRunLoopGetCurrent(),
                                      kCFRunLoopDefaultMode);

   // start the event stream (check for errors and release if necessary
   if (!::FSEventStreamStart(pContext->streamRef))
   {
      invalidateAndReleaseEventStream(pContext->streamRef);

      callbacks.onRegistrationError(systemError(
                                       boost::system::errc::no_stream_resources,
                                       ERROR_LOCATION));
      return Handle();
   }

   // scan the files
   Error error = scanFiles(FileInfo(filePath),
                           recursive,
                           filter,
                           &pContext->fileTree);
   if (error)
   {
       // stop, invalidate, release
       stopInvalidateAndReleaseEventStream(pContext->streamRef);

       // return error
       callbacks.onRegistrationError(error);
       return Handle();
   }

   // now that we have finished the file listing we know we have a valid
   // file-monitor so set the callbacks
   pContext->callbacks = callbacks;

   // we are going to pass the context pointer to the client (as the Handle)
   // so we release it here to relinquish ownership
   autoPtrContext.release();

   // notify the caller that we have successfully registered
   callbacks.onRegistered(pContext->handle, pContext->fileTree);

   // return the handle
   return pContext->handle;
}
void
CollectionScanner::doJob() //SLOT
{
    if( !m_restart )
    {
        std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
        std::cout << "<scanner>";
    }

    QStringList entries;

    if( m_restart )
    {
        QFile logFile( m_logfile );
        QString lastFile;
        if( logFile.open( QIODevice::ReadOnly ) )
        {
            QTextStream logStream;
            logStream.setDevice(&logFile);
            logStream.setCodec(QTextCodec::codecForName( "UTF-8" ) );
            lastFile = logStream.readAll();
            logFile.close();
        }

        QFile folderFile;
        if( !m_batch )
            folderFile.setFileName( m_saveLocation  + "collection_scan.files"   );
        else if( m_incremental )
            folderFile.setFileName( "amarokcollectionscanner_batchincrementalscan.files" );
        else
            folderFile.setFileName( "amarokcollectionscanner_batchfullscan.files" );
        if( folderFile.open( QIODevice::ReadOnly ) )
        {
            QTextStream folderStream;
            folderStream.setDevice(&folderFile);
            folderStream.setCodec( QTextCodec::codecForName( "UTF-8" ) );
            entries = folderStream.readAll().split( '\n' );
        }

        for( int count = entries.indexOf( lastFile ) + 1; count; --count )
            entries.pop_front();
    }
    else
    {
        foreach( QString dir, m_folders ) // krazy:exclude=foreach
        {
            if( dir.isEmpty() )
                //apparently somewhere empty strings get into the mix
                //which results in a full-system scan! Which we can't allow
                continue;

            // Make sure that all paths are absolute, not relative
            if( QDir::isRelativePath( dir ) )
                dir = QDir::cleanPath( QDir::currentPath() + '/' + dir );
 
            if( !dir.endsWith( '/' ) )
                dir += '/';

            readDir( dir, entries );
        }

        QFile folderFile;
        if( !m_batch )
            folderFile.setFileName( m_saveLocation + "collection_scan.files" );
        else if( m_incremental )
            folderFile.setFileName( "amarokcollectionscanner_batchincrementalscan.files" );
        else
            folderFile.setFileName( "amarokcollectionscanner_batchfullscan.files" );
        if ( folderFile.open( QIODevice::WriteOnly ) )
        {
            QTextStream stream( &folderFile );
            stream.setCodec( QTextCodec::codecForName("UTF-8") );
            stream << entries.join( "\n" );
            folderFile.close();
        }
    }

    if( !entries.isEmpty() )
    {
        if( !m_restart )
        {
            AttributeHash attributes;
            attributes["count"] = QString::number( entries.count() );
            writeElement( "itemcount", attributes );
        }

        scanFiles( entries );
    }

    std::cout << "</scanner>" << std::endl;

    if( m_batch )
    {
        if( m_incremental )
        {
            QFile::remove( "amarokcollectionscanner_batchincrementalscan.files" );
            QFile::remove( "amarokcollectionscanner_batchincrementalscan.log" );
        }
        else
        {
            QFile::remove( "amarokcollectionscanner_batchfullscan.files" );
            QFile::remove( "amarokcollectionscanner_batchfullscan.log" );
        }
    }
    
    quit();
}
Example #10
0
Error discoverAndProcessFileChanges(
   const FileInfo& fileInfo,
   bool recursive,
   const boost::function<bool(const FileInfo&)>& filter,
   const boost::function<Error(const FileInfo&)>& onBeforeScanDir,
   tree<FileInfo>* pTree,
   const  boost::function<void(const std::vector<FileChangeEvent>&)>&
                                                               onFilesChanged)
{
   // find this path in our fileTree
   tree<FileInfo>::iterator it = std::find(pTree->begin(),
                                           pTree->end(),
                                           fileInfo);

   // if we don't find it then it may have been excluded by a filter, just bail
   if (it == pTree->end())
      return Success();

   // scan this directory into a new tree which we can compare to the old tree
   tree<FileInfo> subdirTree;
   FileScannerOptions options;
   options.recursive = recursive;
   options.yield = true;
   options.filter = filter;
   options.onBeforeScanDir = onBeforeScanDir;
   Error error = scanFiles(fileInfo, options, &subdirTree);
   if (error)
      return error;

   // handle recursive vs. non-recursive scan differnetly
   if (recursive)
   {
      // check for changes on full subtree
      std::vector<FileChangeEvent> fileChanges;
      tree<FileInfo> existingSubtree(it);
      collectFileChangeEvents(existingSubtree.begin(),
                              existingSubtree.end(),
                              subdirTree.begin(),
                              subdirTree.end(),
                              &fileChanges);

      // fire events
      onFilesChanged(fileChanges);

      // wholesale replace subtree
      pTree->insert_subtree_after(it, subdirTree.begin());
      pTree->erase(it);
   }
   else
   {
      // scan for changes on just the children
      std::vector<FileChangeEvent> childrenFileChanges;
      collectFileChangeEvents(pTree->begin(it),
                              pTree->end(it),
                              subdirTree.begin(subdirTree.begin()),
                              subdirTree.end(subdirTree.begin()),
                              &childrenFileChanges);

      // build up actual file changes and mutate the tree as appropriate
      std::vector<FileChangeEvent> fileChanges;
      BOOST_FOREACH(const FileChangeEvent& fileChange, childrenFileChanges)
      {
         switch(fileChange.type())
         {
         case FileChangeEvent::FileAdded:
         {
            Error error = processFileAdded(it,
                                           fileChange,
                                           recursive,
                                           filter,
                                           pTree,
                                           &fileChanges);
            if (error)
               LOG_ERROR(error);
            break;
         }
         case FileChangeEvent::FileModified:
         {
            processFileModified(it, fileChange, pTree, &fileChanges);
            break;
         }
         case FileChangeEvent::FileRemoved:
         {
            processFileRemoved(it,
                               fileChange,
                               recursive,
                               pTree,
                               &fileChanges);
            break;
         }
         case FileChangeEvent::None:
         default:
            break;
         }
      }

      // fire events
      onFilesChanged(fileChanges);
   }

   return Success();
}