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

Task: Store the mrl in the item

parent 85c191ec
......@@ -1006,8 +1006,8 @@ void MediaLibrary::migrateModel10to11()
auto t = getConn()->newTransaction();
for ( const auto& t : tasks )
{
auto newMrl = utils::url::encode( utils::url::decode( t->mrl ) );
LOG_INFO( "Converting task mrl: ", t->mrl, " to ", newMrl );
auto newMrl = utils::url::encode( utils::url::decode( t->item().mrl() ) );
LOG_INFO( "Converting task mrl: ", t->item().mrl(), " to ", newMrl );
t->setMrl( std::move( newMrl ) );
}
for ( const auto &f : folders )
......
......@@ -109,14 +109,15 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
{
assert( task.media == nullptr );
// Try to create Media & File
auto mrl = task.item().mrl();
try
{
auto t = m_ml->getConn()->newTransaction();
LOG_INFO( "Adding ", task.mrl );
task.media = Media::create( m_ml, IMedia::Type::Unknown, utils::file::fileName( task.mrl ) );
LOG_INFO( "Adding ", mrl );
task.media = Media::create( m_ml, IMedia::Type::Unknown, utils::file::fileName( mrl ) );
if ( task.media == nullptr )
{
LOG_ERROR( "Failed to add media ", task.mrl, " to the media library" );
LOG_ERROR( "Failed to add media ", mrl, " to the media library" );
return parser::Task::Status::Fatal;
}
// For now, assume all media are made of a single file
......@@ -125,7 +126,7 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
File::Type::Main );
if ( task.file == nullptr )
{
LOG_ERROR( "Failed to add file ", task.mrl, " to media #", task.media->id() );
LOG_ERROR( "Failed to add file ", mrl, " to media #", task.media->id() );
return parser::Task::Status::Fatal;
}
task.updateFileId();
......@@ -137,10 +138,10 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
LOG_INFO( "Creation of Media & File failed because ", ex.what(),
". Assuming this task is a duplicate" );
// Try to retrieve file & Media from database
auto fileInDB = File::fromMrl( m_ml, task.mrl );
auto fileInDB = File::fromMrl( m_ml, mrl );
if ( fileInDB == nullptr ) // The file is no longer present in DB, gracefully delete task
{
LOG_ERROR( "File ", task.mrl, " no longer present in DB, aborting");
LOG_ERROR( "File ", mrl, " no longer present in DB, aborting");
return parser::Task::Status::Fatal;
}
task.file = fileInDB;
......@@ -229,20 +230,21 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
bool MetadataParser::addPlaylistMedias( parser::Task& task, int nbSubitem ) const
{
auto t = m_ml->getConn()->newTransaction();
LOG_INFO( "Try to import ", task.mrl, " as a playlist" );
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( task.mrl ) );
playlistName = utils::url::decode( utils::file::fileName( mrl ) );
auto playlistPtr = Playlist::create( m_ml, playlistName );
if ( playlistPtr == nullptr )
{
LOG_ERROR( "Failed to create playlist ", task.mrl, " to the media library" );
LOG_ERROR( "Failed to create playlist ", mrl, " to the media library" );
return false;
}
task.file = playlistPtr->addFile( *task.fileFs, task.parentFolder->id(), task.parentFolderFs->device()->isRemovable() );
if ( task.file == nullptr )
{
LOG_ERROR( "Failed to add playlist file ", task.mrl );
LOG_ERROR( "Failed to add playlist file ", mrl );
return false;
}
t->commit();
......@@ -259,11 +261,11 @@ void MetadataParser::addPlaylistElement( parser::Task& task, const std::shared_p
if ( subitem == nullptr )
return;
const auto& mrl = subitem->mrl();
LOG_INFO( "Try to add ", mrl, " to the playlist ", task.mrl );
LOG_INFO( "Try to add ", mrl, " to the playlist ", mrl );
auto media = m_ml->media( mrl );
if ( media != nullptr )
{
LOG_INFO( "Media for ", mrl, " already exists, adding it to the playlist ", task.mrl );
LOG_INFO( "Media for ", mrl, " already exists, adding it to the playlist ", mrl );
playlistPtr->add( media->id(), index );
return;
}
......@@ -277,13 +279,13 @@ void MetadataParser::addPlaylistElement( parser::Task& task, const std::shared_p
subitem->meta( libvlc_meta_Title ) ) );
if ( externalMedia == nullptr )
{
LOG_ERROR( "Failed to create external media for ", mrl, " in the playlist ", task.mrl );
LOG_ERROR( "Failed to create external media for ", subitem->mrl(), " in the playlist ", mrl );
return;
}
// Assuming that external mrl present in playlist file is a main media resource
auto externalFile = externalMedia->addExternalMrl( mrl, IFile::Type::Main );
if ( externalFile == nullptr )
LOG_ERROR( "Failed to create external file for ", mrl, " in the playlist ", task.mrl );
LOG_ERROR( "Failed to create external file for ", subitem->mrl(), " in the playlist ", mrl );
playlistPtr->add( externalMedia->id(), index );
t2->commit();
return;
......@@ -298,7 +300,7 @@ void MetadataParser::addPlaylistElement( parser::Task& task, const std::shared_p
LOG_ERROR( ex.what() );
return;
}
LOG_INFO( "Importing ", isDirectory ? "folder " : "file ", mrl, " in the playlist ", task.mrl );
LOG_INFO( "Importing ", isDirectory ? "folder " : "file ", subitem->mrl(), " in the playlist ", mrl );
auto directoryMrl = utils::file::directory( mrl );
auto parentFolder = Folder::fromMrl( m_ml, directoryMrl );
bool parentKnown = parentFolder != nullptr;
......
......@@ -49,7 +49,7 @@ bool VLCMetadataService::initialize( MediaLibrary* ml )
parser::Task::Status VLCMetadataService::run( parser::Task& task )
{
auto mrl = task.mrl;
auto mrl = task.item().mrl();
LOG_INFO( "Parsing ", mrl );
// Having a valid media means we're re-executing this parser after the thumbnailer,
......
......@@ -164,14 +164,14 @@ void ParserWorker::mainloop()
}
if ( m_service->isCompleted( *task ) == true )
{
LOG_INFO( "Skipping completed task [", serviceName, "] on ", task->mrl );
LOG_INFO( "Skipping completed task [", serviceName, "] on ", task->item().mrl() );
m_parserCb->done( std::move( task ), parser::Task::Status::Success );
continue;
}
parser::Task::Status status;
try
{
LOG_INFO( "Executing ", serviceName, " task on ", task->mrl );
LOG_INFO( "Executing ", serviceName, " task on ", task->item().mrl() );
auto chrono = std::chrono::steady_clock::now();
if ( ( task->file != nullptr && task->file->isDeleted() )
|| ( task->media != nullptr && task->media->isDeleted() ) )
......@@ -181,13 +181,13 @@ void ParserWorker::mainloop()
task->startParserStep();
status = m_service->run( *task );
auto duration = std::chrono::steady_clock::now() - chrono;
LOG_INFO( "Done executing ", serviceName, " task on ", task->mrl, " in ",
LOG_INFO( "Done executing ", serviceName, " task on ", task->item().mrl(), " in ",
std::chrono::duration_cast<std::chrono::milliseconds>( duration ).count(), "ms" );
}
}
catch ( const std::exception& ex )
{
LOG_ERROR( "Caught an exception during ", task->mrl, " [", serviceName, "] parsing: ", ex.what() );
LOG_ERROR( "Caught an exception during ", task->item().mrl(), " [", serviceName, "] parsing: ", ex.what() );
status = parser::Task::Status::Fatal;
}
m_parserCb->done( std::move( task ), status );
......
......@@ -50,6 +50,7 @@ Task::Task( MediaLibraryPtr ml, sqlite::Row& row )
: currentService( 0 )
, m_ml( ml )
{
std::string mrl;
row >> m_id
>> m_step
>> m_retryCount
......@@ -58,6 +59,7 @@ Task::Task( MediaLibraryPtr ml, sqlite::Row& row )
>> m_parentFolderId
>> m_parentPlaylistId
>> parentPlaylistIndex;
m_item = Item{ std::move( mrl ) };
}
Task::Task( MediaLibraryPtr ml, std::shared_ptr<fs::IFile> fileFs,
......@@ -70,11 +72,11 @@ Task::Task( MediaLibraryPtr ml, std::shared_ptr<fs::IFile> fileFs,
, parentFolderFs( std::move( parentFolderFs ) )
, parentPlaylist( std::move( parentPlaylist ) )
, parentPlaylistIndex( parentPlaylistIndex )
, mrl( this->fileFs->mrl() )
, currentService( 0 )
, m_ml( ml )
, m_step( ParserStep::None )
, m_fileId( 0 )
, m_item( this->fileFs->mrl() )
{
}
......@@ -135,6 +137,11 @@ Task::Item& Task::item()
return m_item;
}
Task::Item::Item( std::string mrl )
: m_mrl( std::move( mrl ) )
{
}
std::string Task::Item::meta( Task::Item::Metadata type ) const
{
auto it = m_metadata.find( type );
......@@ -148,12 +155,17 @@ void Task::Item::setMeta( Task::Item::Metadata type, std::string value )
m_metadata[type] = std::move( value );
}
const std::string& Task::Item::mrl() const
{
return m_mrl;
}
bool Task::restoreLinkedEntities()
{
LOG_INFO("Restoring linked entities of task ", m_id);
// MRL will be empty if the task has been resumed from unparsed files
// parentFolderId == 0 indicates an external file
if ( mrl.empty() == true && m_parentFolderId == 0 )
if ( m_item.mrl().empty() == true && m_parentFolderId == 0 )
{
LOG_WARN( "Aborting & removing external file task (#", m_id, ')' );
destroy( m_ml, m_id );
......@@ -166,7 +178,7 @@ bool Task::restoreLinkedEntities()
// We might re-create tasks without mrl to ease the handling of files on
// external storage.
if ( mrl.empty() == true )
if ( m_item.mrl().empty() == true )
{
// but we expect those to be created from an existing file after a
// partial/failed migration. If we don't have a file nor an mrl, we
......@@ -193,13 +205,13 @@ bool Task::restoreLinkedEntities()
}
setMrl( file->mrl() );
}
auto fsFactory = m_ml->fsFactoryForMrl( mrl );
auto fsFactory = m_ml->fsFactoryForMrl( m_item.mrl() );
if ( fsFactory == nullptr )
return false;
try
{
parentFolderFs = fsFactory->createDirectory( utils::file::directory( mrl ) );
parentFolderFs = fsFactory->createDirectory( utils::file::directory( m_item.mrl() ) );
}
catch ( const std::system_error& ex )
{
......@@ -211,11 +223,11 @@ bool Task::restoreLinkedEntities()
{
auto files = parentFolderFs->files();
auto it = std::find_if( begin( files ), end( files ), [this]( std::shared_ptr<fs::IFile> f ) {
return f->mrl() == mrl;
return f->mrl() == m_item.mrl();
});
if ( it == end( files ) )
{
LOG_ERROR( "Failed to restore fs::IFile associated with ", mrl );
LOG_ERROR( "Failed to restore fs::IFile associated with ", m_item.mrl() );
return false;
}
fileFs = *it;
......@@ -226,7 +238,7 @@ bool Task::restoreLinkedEntities()
// recreated upon next discovery
if ( file == nullptr )
{
LOG_WARN( "Failed to restore file system instances for mrl ", mrl, "."
LOG_WARN( "Failed to restore file system instances for mrl ", m_item.mrl(), "."
" Removing the task until it gets detected again." );
destroy( m_ml, m_id );
}
......@@ -236,7 +248,7 @@ bool Task::restoreLinkedEntities()
// detect that the file is now missing, and we won't try to restore
// this task until it comes back (since the task restoration request
// includes the file.is_present flag)
LOG_WARN( "Failed to restore file system instances for mrl ", mrl, "."
LOG_WARN( "Failed to restore file system instances for mrl ", m_item.mrl(), "."
" Postponing the task." );
}
return false;
......@@ -254,13 +266,13 @@ bool Task::restoreLinkedEntities()
void Task::setMrl( std::string newMrl )
{
if ( mrl == newMrl )
if ( m_item.mrl() == newMrl )
return;
static const std::string req = "UPDATE " + policy::TaskTable::Name + " SET "
"mrl = ? WHERE id_task = ?";
if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, newMrl, m_id ) == false )
return;
mrl = std::move( newMrl );
m_item = Item{ std::move( newMrl ) };
}
void Task::createTable( sqlite::Connection* dbConnection )
......@@ -321,7 +333,7 @@ Task::create( MediaLibraryPtr ml, std::shared_ptr<fs::IFile> fileFs,
const std::string req = "INSERT INTO " + policy::TaskTable::Name +
"(mrl, parent_folder_id, parent_playlist_id, parent_playlist_index) "
"VALUES(?, ?, ?, ?)";
if ( insert( ml, self, req, self->mrl, self->parentFolder->id(), sqlite::ForeignKey(
if ( insert( ml, self, req, self->m_item.mrl(), self->parentFolder->id(), sqlite::ForeignKey(
self->parentPlaylist ? self->parentPlaylist->id() : 0 ),
self->parentPlaylistIndex ) == false )
return nullptr;
......
......@@ -92,6 +92,8 @@ public:
class Item
{
public:
Item() = default;
Item( std::string mrl );
enum class Metadata : uint8_t
{
Title,
......@@ -110,7 +112,10 @@ public:
std::string meta( Metadata type ) const;
void setMeta( Metadata type, std::string value );
const std::string& mrl() const;
private:
std::string m_mrl;
std::unordered_map<Metadata, std::string> m_metadata;
};
......@@ -159,7 +164,6 @@ public:
std::shared_ptr<fs::IDirectory> parentFolderFs;
std::shared_ptr<Playlist> parentPlaylist;
unsigned int parentPlaylistIndex;
std::string mrl;
VLC::Media vlcMedia;
unsigned int currentService;
......
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