Commit aec7f3d4 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

IMediaLibrary: Allow a full rescan to be triggered

parent 267ed2b3
......@@ -359,6 +359,15 @@ class IMediaLibrary
* This must be called *before* initialize()
*/
virtual IDeviceListerCb* setDeviceLister( DeviceListerPtr lister ) = 0;
/**
* @brief forceRescan forces all media to be rescanned.
*
* This can be called anytime after the medialibrary has been initialized.
* It will make all held instances outdated. Those should be considered
* as invalid the moment this method returns.
*/
virtual void forceRescan() = 0;
};
}
......
......@@ -330,4 +330,11 @@ void File::resetRetryCount( MediaLibraryPtr ml )
sqlite::Tools::executeUpdate( ml->getConn(), req, parser::Task::ParserStep::Completed );
}
void File::resetParsing( MediaLibraryPtr ml )
{
static const std::string req = "UPDATE " + policy::FileTable::Name + " SET "
"parser_retries = 0, parser_step = ?";
sqlite::Tools::executeUpdate( ml->getConn(), req, parser::Task::ParserStep::None );
}
}
......@@ -112,6 +112,7 @@ public:
static std::vector<std::shared_ptr<File>> fetchUnparsed( MediaLibraryPtr ml );
static void resetRetryCount( MediaLibraryPtr ml );
static void resetParsing( MediaLibraryPtr ml );
private:
MediaLibraryPtr m_ml;
......
......@@ -1067,6 +1067,32 @@ void MediaLibrary::refreshDevices( factory::IFileSystem& fsFactory )
}
}
void MediaLibrary::forceRescan()
{
if ( m_parser != nullptr )
{
m_parser->pause();
// Flush current tasks
}
{
auto t = getConn()->newTransaction();
// The triggers will automatically albums and album tracks
Artist::deleteAll( this );
Movie::deleteAll( this );
// The triggers will delete the associated episodes
Show::deleteAll( this );
VideoTrack::deleteAll( this );
AudioTrack::deleteAll( this );
File::resetParsing( this );
clearCache();
}
if ( m_parser != nullptr )
{
m_parser->restore();
m_parser->resume();
}
}
bool MediaLibrary::onDevicePlugged( const std::string& uuid, const std::string& mountpoint )
{
auto currentDevice = Device::fromUuid( this, uuid );
......
......@@ -151,6 +151,8 @@ class MediaLibrary : public IMediaLibrary, public IDeviceListerCb
void refreshDevices(factory::IFileSystem& fsFactory);
virtual void forceRescan() override;
static bool isExtensionSupported( const char* ext );
protected:
......
......@@ -114,6 +114,12 @@ void Parser::stop()
}
}
void Parser::flush()
{
for ( auto& s : m_services )
s->flush();
}
void Parser::restore()
{
if ( m_services.empty() == true )
......
......@@ -60,10 +60,11 @@ public:
void pause();
void resume();
void stop();
private:
void flush();
// Queues all unparsed files for parsing.
void restore();
private:
void updateStats();
virtual void done( std::unique_ptr<parser::Task> task, parser::Task::Status status ) override;
virtual void onIdleChanged( bool idle ) override;
......
......@@ -117,6 +117,17 @@ bool ParserService::isIdle() const
return m_idle;
}
void ParserService::flush()
{
std::unique_lock<compat::Mutex> lock( m_lock );
assert( m_paused == true || m_threads.empty() == true );
m_idleCond.wait( lock, [this]() {
return m_idle == true;
});
while ( m_tasks.empty() == false )
m_tasks.pop();
}
uint8_t ParserService::nbNativeThreads() const
{
auto nbProcs = static_cast<uint8_t>( compat::Thread::hardware_concurrency() );
......@@ -148,6 +159,7 @@ void ParserService::mainloop()
{
LOG_INFO( "Halting ParserService [", serviceName, "] mainloop" );
setIdle( true );
m_idleCond.notify_all();
m_cond.wait( lock, [this]() {
return ( m_tasks.empty() == false && m_paused == false )
|| m_stopParser == true;
......
......@@ -62,6 +62,12 @@ public:
void parse( std::unique_ptr<parser::Task> t );
void initialize( MediaLibrary* mediaLibrary, IParserCb* parserCb );
bool isIdle() const;
///
/// \brief flush flush every currently scheduled tasks
///
/// The service needs to be previously paused or unstarted
///
void flush();
protected:
uint8_t nbNativeThreads() const;
......@@ -89,6 +95,7 @@ private:
bool m_paused;
std::atomic_bool m_idle;
compat::ConditionVariable m_cond;
compat::ConditionVariable m_idleCond;
std::queue<std::unique_ptr<parser::Task>> m_tasks;
std::vector<compat::Thread> m_threads;
compat::Mutex m_lock;
......
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