Commit c6ba8ad5 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen
Browse files

MetadataParser: Properly handle playlist rescan

parent 3ed4e89f
......@@ -1292,7 +1292,7 @@ void MediaLibrary::forceRescan()
Show::deleteAll( this );
VideoTrack::deleteAll( this );
AudioTrack::deleteAll( this );
Playlist::deleteAllExternal( this );
Playlist::clearExternalPlaylistContent( this );
parser::Task::resetParsing( this );
clearCache();
Artist::createDefaultArtists( getConn() );
......
......@@ -278,10 +278,15 @@ Query<IPlaylist> Playlist::listAll( MediaLibraryPtr ml, SortingCriteria sort, bo
return make_query<Playlist, IPlaylist>( ml, "*", req );
}
void Playlist::deleteAllExternal(MediaLibraryPtr ml)
void Playlist::clearExternalPlaylistContent(MediaLibraryPtr ml)
{
const std::string req = "DELETE FROM " + policy::PlaylistTable::Name +
" WHERE file_id IS NOT NULL";
// We can't delete all external playlist as such, since this would cause the
// deletion of the associated task through the Task.playlist_id Playlist.id_playlist
// foreign key, and therefor they wouldn't be rescanned.
// Instead, flush the playlist content.
const std::string req = "DELETE FROM PlaylistMediaRelation WHERE playlist_id IN ("
"SELECT id_playlist FROM " + policy::PlaylistTable::Name + " WHERE "
"file_id IS NOT NULL)";
sqlite::Tools::executeDelete( ml->getConn(), req );
}
......
......@@ -78,7 +78,7 @@ public:
* that were parsed from playlist files.
* Playlist manually added by the user are untouched
*/
static void deleteAllExternal( MediaLibraryPtr ml );
static void clearExternalPlaylistContent( MediaLibraryPtr ml );
private:
static std::string sortRequest( SortingCriteria sort, bool desc );
......
......@@ -235,28 +235,54 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
bool MetadataParser::addPlaylistMedias( parser::Task& task ) const
{
auto t = m_ml->getConn()->newTransaction();
const auto& mrl = task.item().mrl();
LOG_INFO( "Try to import ", mrl, " as a playlist" );
auto playlistName = task.item().meta( parser::Task::Item::Metadata::Title );
if ( playlistName.empty() == true )
playlistName = utils::url::decode( utils::file::fileName( mrl ) );
auto playlistPtr = Playlist::create( m_ml, playlistName );
if ( playlistPtr == nullptr )
{
LOG_ERROR( "Failed to create playlist ", mrl, " to the media library" );
return false;
std::shared_ptr<Playlist> playlistPtr;
if ( task.item().file() != nullptr )
{
// We are most likely re-scanning a file representing a playlist.
// If a task has a file, it means the playlist & the associated file have
// been created.
std::string req = "SELECT * FROM " + policy::PlaylistTable::Name +
" WHERE file_id = ?";
playlistPtr = Playlist::fetch( m_ml, req, task.item().file()->id() );
if ( playlistPtr == nullptr )
{
// The playlist had to be created, something is very wrong, give up
// FIXME: Check that the task will be deleted.
assert( false );
return false;
}
}
auto file = playlistPtr->addFile( *task.item().fileFs(),
task.item().parentFolder()->id(),
task.item().parentFolderFs()->device()->isRemovable() );
if ( file == nullptr )
else
{
LOG_ERROR( "Failed to add playlist file ", mrl );
return false;
auto playlistName = task.item().meta( parser::Task::Item::Metadata::Title );
if ( playlistName.empty() == true )
playlistName = utils::url::decode( utils::file::fileName( mrl ) );
auto t = m_ml->getConn()->newTransaction();
playlistPtr = Playlist::create( m_ml, playlistName );
if ( playlistPtr == nullptr )
{
LOG_ERROR( "Failed to create playlist ", mrl, " to the media library" );
return false;
}
auto file = playlistPtr->addFile( *task.item().fileFs(),
task.item().parentFolder()->id(),
task.item().parentFolderFs()->device()->isRemovable() );
if ( file == nullptr )
{
LOG_ERROR( "Failed to add playlist file ", mrl );
return false;
}
task.item().setFile( std::move( file ) );
t->commit();
}
task.item().setFile( std::move( file ) );
t->commit();
// Now regardless of if the playlist is re-scanned or discovered from the
// first time, just schedule all members for insertion. media & files will
// be recreated if need be, and appropriate entries in PlaylistMediaRelation
// table will be recreated to link things together.
auto subitems = task.item().subItems();
for ( const auto& subItem : subitems ) // FIXME: Interrupt loop if paused
addPlaylistElement( task, playlistPtr, subItem );
......
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