Commit e4d9d3c9 authored by Alexandre Fernandez's avatar Alexandre Fernandez

Prober: Add interface to abstract different discoverer behavior

parent 5a931a70
......@@ -64,6 +64,7 @@ libmedialibrary_la_SOURCES = \
src/database/SqliteTransaction.cpp \
src/discoverer/DiscovererWorker.cpp \
src/discoverer/FsDiscoverer.cpp \
src/discoverer/probe/PathProbe.cpp \
src/factory/FileSystemFactory.cpp \
src/factory/NetworkFileSystemFactory.cpp \
src/factory/DeviceListerFactory.cpp \
......@@ -126,6 +127,9 @@ noinst_HEADERS = \
src/Device.h \
src/discoverer/DiscovererWorker.h \
src/discoverer/FsDiscoverer.h \
src/discoverer/probe/CrawlerProbe.h \
src/discoverer/probe/IProbe.h \
src/discoverer/probe/PathProbe.h \
src/factory/FileSystemFactory.h \
src/factory/NetworkFileSystemFactory.h \
src/factory/DeviceListerFactory.h \
......
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2017 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
* Alexandre Fernandez <nerf@boboop.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include "discoverer/probe/IProbe.h"
namespace medialibrary
{
namespace prober
{
class CrawlerProbe : public IProbe
{
public:
CrawlerProbe() = default;
void setDiscoverNoMedia( bool discoverNoMedia )
{
m_discoverNoMedia = discoverNoMedia;
}
virtual bool proceedOnDirectory( const fs::IDirectory& ) override
{
return true;
}
virtual bool isHidden( const fs::IDirectory& directory ) override
{
bool hidden = m_discoverNoMedia == false && hasDotNoMediaFile( directory ) == true;
if ( hidden == true )
LOG_INFO( "Ignoring folder ", directory.mrl(), " with a .nomedia file" );
return hidden;
}
virtual bool proceedOnFile( const fs::IFile& ) override
{
return true;
}
virtual bool stopFileDiscovery() override
{
return false;
}
virtual bool deleteUnseenFolders() override
{
return true;
}
virtual bool deleteUnseenFiles() override
{
return true;
}
virtual bool forceFileRefresh() override
{
return false;
}
virtual std::shared_ptr<Folder> getFolderParent() override
{
return nullptr;
}
virtual std::pair<std::shared_ptr<Playlist>, unsigned int> getPlaylistParent() override
{
return { nullptr, 0 };
}
private:
static bool hasDotNoMediaFile( const fs::IDirectory& directory )
{
const auto& files = directory.files();
return std::find_if( begin( files ), end( files ), []( const std::shared_ptr<fs::IFile>& file ){
return strcasecmp( file->name().c_str(), ".nomedia" ) == 0;
}) != end( files );
}
private:
bool m_discoverNoMedia; // Initialized to false
};
}
}
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2017 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
* Alexandre Fernandez <nerf@boboop.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include <memory>
namespace medialibrary
{
class Playlist;
class Folder;
namespace fs
{
class IDirectory;
class IFile;
}
namespace prober
{
class IProbe
{
public:
virtual ~IProbe() = default;
/**
* @brief proceedOnDirectory Decide whether or not the FsDiscoverer should scan a directory
*/
virtual bool proceedOnDirectory( const fs::IDirectory& directory ) = 0;
/**
* @brief isHidden Inform the FsDiscoverer if directory is considered hidden or not
*/
virtual bool isHidden( const fs::IDirectory& directory ) = 0;
/**
* @brief proceedOnFile Decide if the FsDiscoverer should check a file or ignore it
*/
virtual bool proceedOnFile( const fs::IFile& file ) = 0;
/**
* @brief stopFileDiscovery Tell the FsDiscoverer if whe should stop the scan for optimisation purpose
*/
virtual bool stopFileDiscovery() = 0;
/**
* @brief proceedOnDirectory Decide if the FsDiscoverer should delete folders not found on the file system
*/
virtual bool deleteUnseenFolders() = 0;
/**
* @brief deleteUnseenFiles Decide if the FsDiscoverer should delete files not found on the file system
*/
virtual bool deleteUnseenFiles() = 0;
/**
* @brief forceFileRefresh Decide if we force-add discovered files to filesToAdd, like if it was new ones
*/
virtual bool forceFileRefresh() = 0;
virtual std::shared_ptr<Folder> getFolderParent() = 0;
virtual std::pair<std::shared_ptr<Playlist>, unsigned int> getPlaylistParent() = 0;
};
}
}
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2017 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
* Alexandre Fernandez <nerf@boboop.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <cassert>
#include <utility>
#include "discoverer/probe/PathProbe.h"
#include "utils/Filename.h"
#include "filesystem/IDirectory.h"
#include "filesystem/IFile.h"
namespace medialibrary
{
namespace prober
{
PathProbe::PathProbe( const std::string& path, bool isDirectory, std::shared_ptr<Playlist> parentPlaylist,
std::shared_ptr<Folder> parentFolder, const std::string& parentFolderPath,
unsigned int playlistIndex, bool reload )
: m_isDirectory( isDirectory )
, m_isDiscoveryEnded( false )
, m_parentPlaylist( std::move( parentPlaylist ) )
, m_parentFolder( std::move( parentFolder ) )
, m_path( path )
, m_playlistIndex( playlistIndex )
{
assert( path.size() >= parentFolderPath.size() );
m_splitPath = utils::file::splitPath( path, isDirectory );
// If the parent folder exists, we shorten the stack to contain only new folders
if ( m_parentFolder != nullptr && m_splitPath.empty() == false )
{
auto parentSplit = utils::file::splitPath( parentFolderPath, true );
while ( parentSplit.empty() == false )
{
assert( parentSplit.top() == m_splitPath.top() );
parentSplit.pop();
m_splitPath.pop();
}
}
else if ( reload == true && m_splitPath.empty() == false )
// An existing folder is being reloaded, and won't be unstacked by FsDiscoverer::discover(), so it's done here
m_splitPath.pop();
}
bool PathProbe::proceedOnDirectory( const fs::IDirectory& directory )
{
if ( m_isDirectory && m_splitPath.empty() == true )
{
auto directoryPath = utils::file::toPath( directory.mrl() );
auto comp = std::mismatch( m_path.begin(), m_path.end(), directoryPath.begin());
if ( comp.first == m_path.end() )
return true;
m_isDiscoveryEnded = true;
return false;
}
if ( m_splitPath.empty() == true
|| m_splitPath.top() != utils::file::directoryName( utils::file::toPath( directory.mrl() ) ) )
return false;
m_splitPath.pop();
return true;
}
bool PathProbe::proceedOnFile( const fs::IFile& file )
{
if ( m_isDirectory == true && m_isDiscoveryEnded == false && m_splitPath.empty() == true )
{
if ( utils::file::stripScheme( file.mrl() ) != m_path )
return true;
m_isDiscoveryEnded = true;
return false;
}
if ( m_path == utils::file::stripScheme( file.mrl() ) )
{
assert( m_splitPath.size() == 1 && file.name() == m_splitPath.top() );
m_splitPath.pop();
m_isDiscoveryEnded = true;
return true;
}
return false;
}
}
}
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2017 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
* Alexandre Fernandez <nerf@boboop.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include <string>
#include <stack>
#include <memory>
#include "discoverer/probe/IProbe.h"
namespace medialibrary
{
namespace prober
{
class PathProbe : public IProbe
{
public:
explicit PathProbe( const std::string& path, // The path we target
bool isDirectory, // The PathProbe behave differently between files & folders
std::shared_ptr<Playlist> parentPlaylist, // Playlist to be attach to the file addition task
std::shared_ptr<Folder> parentFolder, // known parent folder to start from, if any
const std::string& parentFolderPath, // known parent folder path
unsigned int playlistIndex,
bool reload );
virtual bool proceedOnDirectory( const fs::IDirectory& directory ) override;
virtual bool isHidden( const fs::IDirectory& ) override
{
// We want to add the provided path without checking for .nomedia files
return false;
}
virtual bool proceedOnFile( const fs::IFile& file ) override;
virtual bool stopFileDiscovery() override
{
return m_isDiscoveryEnded;
}
virtual bool deleteUnseenFolders() override
{
return false;
}
virtual bool deleteUnseenFiles() override
{
return false;
}
virtual bool forceFileRefresh() override
{
return true;
}
virtual std::shared_ptr<Folder> getFolderParent() override
{
return m_parentFolder;
}
virtual std::pair<std::shared_ptr<Playlist>, unsigned int> getPlaylistParent() override
{
return { m_parentPlaylist, m_playlistIndex };
}
private:
bool m_isDirectory;
std::stack<std::string> m_splitPath;
bool m_isDiscoveryEnded;
std::shared_ptr<Playlist> m_parentPlaylist;
std::shared_ptr<Folder> m_parentFolder;
std::string m_path;
unsigned int m_playlistIndex;
};
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment