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

MetadataParser: Create album tracks with an associated genre if any

parent 5f6cbd35
......@@ -230,11 +230,12 @@ std::vector<MediaPtr> Album::cachedTracks() const
return m_tracks.get();
}
std::shared_ptr<AlbumTrack> Album::addTrack( std::shared_ptr<Media> media, unsigned int trackNb, unsigned int discNumber, int64_t artistId )
std::shared_ptr<AlbumTrack> Album::addTrack( std::shared_ptr<Media> media, unsigned int trackNb,
unsigned int discNumber, int64_t artistId, int64_t genreId )
{
auto t = m_ml->getConn()->newTransaction();
auto track = AlbumTrack::create( m_ml, m_id, media, trackNb, discNumber, artistId );
auto track = AlbumTrack::create( m_ml, m_id, media, trackNb, discNumber, artistId, genreId );
if ( track == nullptr )
return nullptr;
media->setAlbumTrack( track );
......
......@@ -88,7 +88,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
/// The media will be added to the tracks cache.
///
std::shared_ptr<AlbumTrack> addTrack( std::shared_ptr<Media> media, unsigned int trackNb,
unsigned int discNumber, int64_t artistId );
unsigned int discNumber, int64_t artistId, int64_t genreId );
unsigned int nbTracks() const override;
unsigned int duration() const override;
......
......@@ -52,12 +52,12 @@ AlbumTrack::AlbumTrack( MediaLibraryPtr ml, sqlite::Row& row )
>> m_isPresent;
}
AlbumTrack::AlbumTrack( MediaLibraryPtr ml, int64_t mediaId, int64_t artistId, unsigned int trackNumber, int64_t albumId, unsigned int discNumber )
AlbumTrack::AlbumTrack( MediaLibraryPtr ml, int64_t mediaId, int64_t artistId, int64_t genreId, unsigned int trackNumber, int64_t albumId, unsigned int discNumber )
: m_ml( ml )
, m_id( 0 )
, m_mediaId( mediaId )
, m_artistId( artistId )
, m_genreId( 0 )
, m_genreId( genreId )
, m_trackNumber( trackNumber )
, m_albumId( albumId )
, m_discNumber( discNumber )
......@@ -126,12 +126,13 @@ bool AlbumTrack::createTable( DBConnection dbConnection )
std::shared_ptr<AlbumTrack> AlbumTrack::create( MediaLibraryPtr ml, int64_t albumId,
std::shared_ptr<Media> media, unsigned int trackNb,
unsigned int discNumber, int64_t artistId )
unsigned int discNumber, int64_t artistId, int64_t genreId )
{
auto self = std::make_shared<AlbumTrack>( ml, media->id(), artistId, trackNb, albumId, discNumber );
auto self = std::make_shared<AlbumTrack>( ml, media->id(), artistId, genreId, trackNb, albumId, discNumber );
static const std::string req = "INSERT INTO " + policy::AlbumTrackTable::Name
+ "(media_id, artist_id, track_number, album_id, disc_number) VALUES(?, ?, ?, ?, ?)";
if ( insert( ml, self, req, media->id(), sqlite::ForeignKey( artistId ), trackNb, albumId, discNumber ) == false )
+ "(media_id, artist_id, genre_id, track_number, album_id, disc_number) VALUES(?, ?, ?, ?, ?, ?)";
if ( insert( ml, self, req, media->id(), sqlite::ForeignKey( artistId ), sqlite::ForeignKey( genreId ),
trackNb, albumId, discNumber ) == false )
return nullptr;
self->m_media = media;
return self;
......
......@@ -55,7 +55,7 @@ class AlbumTrack : public IAlbumTrack, public DatabaseHelpers<AlbumTrack, policy
{
public:
AlbumTrack( MediaLibraryPtr ml, sqlite::Row& row );
AlbumTrack( MediaLibraryPtr ml, int64_t mediaId, int64_t artistId, unsigned int trackNumber,
AlbumTrack( MediaLibraryPtr ml, int64_t mediaId, int64_t artistId, int64_t genreId, unsigned int trackNumber,
int64_t albumId, unsigned int discNumber);
virtual int64_t id() const override;
......@@ -69,8 +69,8 @@ class AlbumTrack : public IAlbumTrack, public DatabaseHelpers<AlbumTrack, policy
virtual std::shared_ptr<IMedia> media() override;
static bool createTable( DBConnection dbConnection );
static std::shared_ptr<AlbumTrack> create( MediaLibraryPtr ml, int64_t albumId,
std::shared_ptr<Media> media, unsigned int trackNb , unsigned int discNumber, int64_t artistId );
static std::shared_ptr<AlbumTrack> create(MediaLibraryPtr ml, int64_t albumId,
std::shared_ptr<Media> media, unsigned int trackNb , unsigned int discNumber, int64_t artistId , int64_t genreId);
static AlbumTrackPtr fromMedia( MediaLibraryPtr ml, int64_t mediaId );
static std::vector<MediaPtr> fromGenre( MediaLibraryPtr ml, int64_t genreId, SortingCriteria sort, bool desc );
static std::vector<MediaPtr> search(DBConnection dbConn, const std::string& title );
......
......@@ -121,8 +121,9 @@ bool MetadataParser::parseAudioFile( parser::Task& task ) const
if ( task.artworkMrl.empty() == false )
task.media->setThumbnail( task.artworkMrl );
auto genre = handleGenre( task );
auto artists = handleArtists( task );
auto album = handleAlbum( task, artists.first, artists.second );
auto album = handleAlbum( task, artists.first, artists.second, genre.get() );
if ( album == nullptr )
{
LOG_WARN( "Failed to get/create associated album" );
......@@ -134,6 +135,20 @@ bool MetadataParser::parseAudioFile( parser::Task& task ) const
return res;
}
std::shared_ptr<Genre> MetadataParser::handleGenre( parser::Task& task ) const
{
if ( task.genre.length() == 0 )
return nullptr;
auto genre = Genre::fromName( m_ml, task.genre );
if ( genre == nullptr )
{
genre = Genre::create( m_ml, task.genre );
if ( genre == nullptr )
LOG_ERROR( "Failed to get/create Genre", task.genre );
}
return genre;
}
/* Album handling */
std::shared_ptr<Album> MetadataParser::findAlbum( parser::Task& task, Artist* albumArtist ) const
{
......@@ -225,7 +240,8 @@ std::shared_ptr<Album> MetadataParser::findAlbum( parser::Task& task, Artist* al
return std::static_pointer_cast<Album>( albums[0] );
}
std::shared_ptr<Album> MetadataParser::handleAlbum( parser::Task& task, std::shared_ptr<Artist> albumArtist, std::shared_ptr<Artist> trackArtist ) const
std::shared_ptr<Album> MetadataParser::handleAlbum( parser::Task& task, std::shared_ptr<Artist> albumArtist,
std::shared_ptr<Artist> trackArtist, Genre* genre ) const
{
std::shared_ptr<Album> album;
std::shared_ptr<Artist> artist = albumArtist;
......@@ -262,7 +278,7 @@ std::shared_ptr<Album> MetadataParser::handleAlbum( parser::Task& task, std::sha
if ( album == nullptr )
return nullptr;
// If we know a track artist, specify it, otherwise, fallback to the album/unknown artist
auto track = handleTrack( album, task, trackArtist ? trackArtist : artist );
auto track = handleTrack( album, task, trackArtist ? trackArtist : artist, genre );
return album;
}
......@@ -317,7 +333,8 @@ std::pair<std::shared_ptr<Artist>, std::shared_ptr<Artist>> MetadataParser::hand
/* Tracks handling */
std::shared_ptr<AlbumTrack> MetadataParser::handleTrack( std::shared_ptr<Album> album, parser::Task& task, std::shared_ptr<Artist> artist ) const
std::shared_ptr<AlbumTrack> MetadataParser::handleTrack( std::shared_ptr<Album> album, parser::Task& task,
std::shared_ptr<Artist> artist, Genre* genre ) const
{
auto title = task.title;
if ( title.empty() == true )
......@@ -332,27 +349,15 @@ std::shared_ptr<AlbumTrack> MetadataParser::handleTrack( std::shared_ptr<Album>
if ( title.empty() == false )
task.media->setTitle( title );
auto track = std::static_pointer_cast<AlbumTrack>( album->addTrack( task.media, task.trackNumber, task.discNumber, artist->id() ) );
auto track = std::static_pointer_cast<AlbumTrack>( album->addTrack( task.media, task.trackNumber,
task.discNumber, artist->id(),
genre != nullptr ? genre->id() : 0 ) );
if ( track == nullptr )
{
LOG_ERROR( "Failed to create album track" );
return nullptr;
}
if ( task.genre.length() != 0 )
{
auto genre = Genre::fromName( m_ml, task.genre );
if ( genre == nullptr )
{
genre = Genre::create( m_ml, task.genre );
if ( genre == nullptr )
{
LOG_ERROR( "Failed to create a genre in database" );
return nullptr;
}
}
track->setGenre( genre );
}
if ( task.releaseDate.empty() == false )
{
auto releaseYear = atoi( task.releaseDate.c_str() );
......
......@@ -42,9 +42,12 @@ protected:
bool parseAudioFile(parser::Task& task) const;
bool parseVideoFile(parser::Task& task) const;
std::pair<std::shared_ptr<Artist>, std::shared_ptr<Artist>> handleArtists( parser::Task& vlcMedia ) const;
std::shared_ptr<AlbumTrack> handleTrack(std::shared_ptr<Album> album, parser::Task& task, std::shared_ptr<Artist> artist) const;
std::shared_ptr<AlbumTrack> handleTrack( std::shared_ptr<Album> album, parser::Task& task,
std::shared_ptr<Artist> artist, Genre* genre ) const;
bool link(Media& media, std::shared_ptr<Album> album, std::shared_ptr<Artist> albumArtist, std::shared_ptr<Artist> artist ) const;
std::shared_ptr<Album> handleAlbum(parser::Task& task, std::shared_ptr<Artist> albumArtist, std::shared_ptr<Artist> artist ) const;
std::shared_ptr<Album> handleAlbum( parser::Task& task, std::shared_ptr<Artist> albumArtist,
std::shared_ptr<Artist> artist, Genre* genre ) const;
std::shared_ptr<Genre> handleGenre( parser::Task& task ) const;
private:
std::shared_ptr<Artist> m_unknownArtist;
......
......@@ -65,7 +65,7 @@ TEST_F( Albums, AddTrack )
{
auto a = ml->createAlbum( "albumtag" );
auto f = ml->addFile( "track.mp3" );
auto track = a->addTrack( f, 10, 0, 0 );
auto track = a->addTrack( f, 10, 0, 0, 0 );
f->save();
ASSERT_NE( track, nullptr );
......@@ -86,7 +86,7 @@ TEST_F( Albums, NbTracks )
for ( auto i = 1u; i <= 10; ++i )
{
auto f = ml->addFile( "track" + std::to_string(i) + ".mp3" );
auto track = a->addTrack( f, i, i, 0 );
auto track = a->addTrack( f, i, i, 0, 0 );
f->save();
ASSERT_NE( track, nullptr );
}
......@@ -108,7 +108,7 @@ TEST_F( Albums, TracksByGenre )
for ( auto i = 1u; i <= 10; ++i )
{
auto f = ml->addFile( "track" + std::to_string(i) + ".mp3" );
auto track = a->addTrack( f, i, i, 0 );
auto track = a->addTrack( f, i, i, 0, 0 );
f->save();
ASSERT_NE( track, nullptr );
if ( i <= 5 )
......@@ -182,7 +182,7 @@ TEST_F( Albums, FetchAlbumFromTrack )
{
auto a = ml->createAlbum( "album" );
auto f = ml->addFile( "file.mp3" );
auto t = a->addTrack( f, 1, 0, 0 );
auto t = a->addTrack( f, 1, 0, 0, 0 );
f->save();
Reload();
......@@ -335,7 +335,7 @@ TEST_F( Albums, AutoDelete )
{
auto a = ml->createAlbum( "album" );
auto m = ml->addFile( "media.mp3" );
auto t = a->addTrack( m, 1, 1, 0 );
auto t = a->addTrack( m, 1, 1, 0, 0 );
auto album = ml->album( a->id() );
ASSERT_NE( nullptr, album );
......@@ -351,8 +351,8 @@ TEST_F( Albums, SortTracks )
auto a = ml->createAlbum( "album" );
auto m1 = ml->addFile( "B-track1.mp3" );
auto m2 = ml->addFile( "A-track2.mp3" );
auto t1 = a->addTrack( m1, 1, 1, 0 );
auto t2 = a->addTrack( m2, 2, 1, 0 );
auto t1 = a->addTrack( m1, 1, 1, 0, 0 );
auto t2 = a->addTrack( m2, 2, 1, 0, 0 );
// Default order is by disc number & track number
auto tracks = a->tracks( SortingCriteria::Default, false );
......@@ -417,13 +417,13 @@ TEST_F( Albums, Duration )
auto m = ml->addFile( "track.mp3" );
m->setDuration( 100 );
m->save();
a->addTrack( m, 1, 1, 0 );
a->addTrack( m, 1, 1, 0, 0 );
ASSERT_EQ( 100u, a->duration() );
auto m2 = ml->addFile( "track2.mp3" );
m2->setDuration( 200 );
m2->save();
a->addTrack( m2, 1, 1, 0 );
a->addTrack( m2, 1, 1, 0, 0 );
ASSERT_EQ( 300u, a->duration() );
Reload();
......
......@@ -40,7 +40,7 @@ TEST_F( AlbumTracks, Create )
{
auto album = ml->createAlbum( "album" );
auto f = ml->addFile( "track1.mp3" );
auto track = album->addTrack( f, 1, 10, 0 );
auto track = album->addTrack( f, 1, 10, 0, 0 );
f->save();
ASSERT_NE( nullptr, track );
ASSERT_EQ( 10u, track->discNumber() );
......@@ -55,7 +55,7 @@ TEST_F( AlbumTracks, Artist )
{
auto album = ml->createAlbum( "album" );
auto f = ml->addFile( "track1.mp3" );
auto track = album->addTrack( f, 1, 0, 0 );
auto track = album->addTrack( f, 1, 0, 0, 0 );
f->save();
auto artist = track->artist();
......@@ -81,7 +81,7 @@ TEST_F( AlbumTracks, SetGenre )
{
auto a = ml->createAlbum( "album" );
auto f = ml->addFile( "track.mp3" );
auto t = a->addTrack( f, 1, 0, 0 );
auto t = a->addTrack( f, 1, 0, 0, 0 );
f->save();
auto genre = ml->createGenre( "happy underground post progressive death metal" );
......@@ -102,7 +102,7 @@ TEST_F( AlbumTracks, Media )
{
auto album = ml->createAlbum( "album" );
auto f = ml->addFile( "track1.mp3" );
auto track = album->addTrack( f, 1, 10, 0 );
auto track = album->addTrack( f, 1, 10, 0, 0 );
f->save();
auto media = track->media();
......@@ -121,7 +121,7 @@ TEST_F( AlbumTracks, Album )
{
auto album = ml->createAlbum( "album" );
auto f = ml->addFile( "track1.mp3" );
auto track = album->addTrack( f, 1, 0, 0 );
auto track = album->addTrack( f, 1, 0, 0, 0 );
f->save();
auto albumFromTrack = track->album();
......
......@@ -260,7 +260,7 @@ TEST_F( DeviceFs, RemoveAlbum )
auto album = std::static_pointer_cast<Album>( ml->createAlbum( "album" ) );
auto media = ml->media( mock::FileSystemFactory::Root + "audio.mp3" );
auto artist = ml->createArtist( "artist" );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1, artist->id() );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1, artist->id(), 0 );
album->setAlbumArtist( artist );
}
// And an album that will disappear, along with its artist
......@@ -269,8 +269,8 @@ TEST_F( DeviceFs, RemoveAlbum )
auto media = ml->media( RemovableDeviceMountpoint + "removablefile.mp3" );
ml->media( RemovableDeviceMountpoint + "removablefile2.mp3" );
auto artist = ml->createArtist( "artist 2" );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1, artist->id() );
album->addTrack( std::static_pointer_cast<Media>( media ), 2, 1, artist->id() );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1, artist->id(), 0 );
album->addTrack( std::static_pointer_cast<Media>( media ), 2, 1, artist->id(), 0 );
album->setAlbumArtist( artist );
}
......@@ -304,8 +304,8 @@ TEST_F( DeviceFs, PartialAlbumRemoval )
auto media = ml->media( mock::FileSystemFactory::SubFolder + "subfile.mp4" );
auto media2 = ml->media( RemovableDeviceMountpoint + "removablefile2.mp3" );
auto newArtist = ml->createArtist( "artist" );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1, newArtist->id() );
album->addTrack( std::static_pointer_cast<Media>( media2 ), 2, 1, newArtist->id() );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1, newArtist->id(), 0 );
album->addTrack( std::static_pointer_cast<Media>( media2 ), 2, 1, newArtist->id(), 0 );
album->setAlbumArtist( newArtist );
newArtist->addMedia( static_cast<Media&>( *media ) );
newArtist->addMedia( static_cast<Media&>( *media2 ) );
......
......@@ -67,7 +67,7 @@ TEST_F( Genres, ListAlbumTracks )
for ( auto i = 1u; i <= 3; i++ )
{
auto m = ml->addFile( "track" + std::to_string( i ) + ".mp3" );
auto t = a->addTrack( m, i, 1, 0 );
auto t = a->addTrack( m, i, 1, 0, 0 );
if ( i != 1 )
t->setGenre( g );
}
......@@ -90,13 +90,13 @@ TEST_F( Genres, ListArtists )
for ( auto i = 1u; i <= 5; ++i )
{
auto m = ml->addFile( std::to_string( i ) + ".mp3" );
auto track = album->addTrack( m, i, 1, a->id() );
auto track = album->addTrack( m, i, 1, a->id(), 0 );
track->setGenre( g );
}
for ( auto i = 1u; i <= 5; ++i )
{
auto m = ml->addFile( std::to_string( i ) + "_2.mp3" );
auto track = album2->addTrack( m, i, 1, a2->id() );
auto track = album2->addTrack( m, i, 1, a2->id(), 0 );
track->setGenre( g );
}
artists = g->artists( SortingCriteria::Default, false );
......@@ -107,12 +107,12 @@ TEST_F( Genres, ListAlbums )
{
auto album = ml->createAlbum( "album" );
auto m = ml->addFile( "some track.mp3" );
auto t = album->addTrack( m, 10, 1, 0 );
auto t = album->addTrack( m, 10, 1, 0, 0 );
t->setGenre( g );
auto album2 = ml->createAlbum( "album2" );
m = ml->addFile( "some other track.mp3" );
t = album2->addTrack( m, 10, 1, 0 );
t = album2->addTrack( m, 10, 1, 0, 0 );
t->setGenre( g );
// We have 2 albums with at least a song with genre "g" (as defined in SetUp)
......@@ -120,7 +120,7 @@ TEST_F( Genres, ListAlbums )
for ( auto i = 1u; i <= 5u; ++i )
{
auto m = ml->addFile( std::to_string( i ) + ".mp3" );
auto track = album->addTrack( m, i, 1, 0 );
auto track = album->addTrack( m, i, 1, 0, 0 );
auto g = ml->createGenre( std::to_string( i ) );
track->setGenre( g );
}
......@@ -170,7 +170,7 @@ TEST_F( Genres, SortTracks )
for ( auto i = 1u; i <= 2; i++ )
{
auto m = ml->addFile( "track" + std::to_string( i ) + ".mp3" );
auto t = a->addTrack( m, i, 1, 0 );
auto t = a->addTrack( m, i, 1, 0, 0 );
m->setDuration( i );
m->save();
t->setGenre( g );
......
......@@ -251,7 +251,7 @@ TEST_F( Medias, SearchTracks )
for ( auto i = 1u; i <= 10u; ++i )
{
auto m = ml->addFile( "track " + std::to_string( i ) + ".mp3" );
a->addTrack( m, i, 1, 0 );
a->addTrack( m, i, 1, 0, 0 );
}
auto tracks = ml->searchMedia( "tra" ).tracks;
ASSERT_EQ( 10u, tracks.size() );
......
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