-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MusicBrainz: Extended metadata support (pre-gsoc2020) #2522
Changes from 6 commits
540c901
745f336
c4e5da7
daacb90
505322f
b0f5991
631b946
064993c
ea59945
c369b63
b805083
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,36 @@ | |
#include <QtDebug> | ||
|
||
#include "library/dlgtagfetcher.h" | ||
#include "track/tracknumbers.h" | ||
|
||
namespace { | ||
|
||
QStringList track2row(const Track& track) { | ||
const auto trackNumbers = TrackNumbers::joinStrings( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This reads as if the return value is a QStringList. I think this is not the case so it is not a good use case for auto. We should also consider to rename the function to makeNumberOfTotalString() |
||
track.getTrackNumber(), | ||
track.getTrackTotal()); | ||
QStringList row; | ||
row.reserve(6); | ||
row | ||
<< track.getYear() | ||
<< track.getAlbum() | ||
<< track.getAlbumArtist() | ||
<< trackNumbers | ||
<< track.getTitle() | ||
<< track.getArtist(); | ||
return row; | ||
} | ||
|
||
void addTrack( | ||
const QStringList& trackRow, | ||
int resultIndex, | ||
QTreeWidget* parent) { | ||
QTreeWidgetItem* item = new QTreeWidgetItem(parent, trackRow); | ||
item->setData(0, Qt::UserRole, resultIndex); | ||
item->setData(0, Qt::TextAlignmentRole, Qt::AlignRight); | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
DlgTagFetcher::DlgTagFetcher(QWidget *parent) | ||
: QDialog(parent), | ||
|
@@ -32,11 +62,12 @@ void DlgTagFetcher::init() { | |
this, &DlgTagFetcher::slotNetworkResult); | ||
|
||
// Resize columns, this can't be set in the ui file | ||
results->setColumnWidth(0, 50); // Track column | ||
results->setColumnWidth(1, 50); // Year column | ||
results->setColumnWidth(2, 160); // Title column | ||
results->setColumnWidth(3, 160); // Artist column | ||
results->setColumnWidth(4, 160); // Album column | ||
results->setColumnWidth(0, 50); // Year column | ||
results->setColumnWidth(1, 160); // Album column | ||
results->setColumnWidth(2, 160); // Album artist column | ||
results->setColumnWidth(3, 50); // Track (numbers) column | ||
results->setColumnWidth(4, 160); // Title column | ||
results->setColumnWidth(5, 160); // Artist column | ||
} | ||
|
||
void DlgTagFetcher::loadTrack(const TrackPointer& track) { | ||
|
@@ -71,23 +102,71 @@ void DlgTagFetcher::slotTrackChanged(TrackId trackId) { | |
void DlgTagFetcher::apply() { | ||
int resultIndex = m_data.m_selectedResult; | ||
if (resultIndex > -1) { | ||
if (!m_data.m_results[resultIndex]->getAlbum().isEmpty()) { | ||
m_track->setAlbum(m_data.m_results[resultIndex]->getAlbum()); | ||
mixxx::TrackMetadata importedMetadata; | ||
m_data.m_results[resultIndex]->readTrackMetadata(&importedMetadata); | ||
mixxx::TrackMetadata updatedMetadata; | ||
m_track->readTrackMetadata(&updatedMetadata); | ||
if (!importedMetadata.getTrackInfo().getArtist().isEmpty()) { | ||
updatedMetadata.refTrackInfo().setArtist( | ||
importedMetadata.getTrackInfo().getArtist()); | ||
} | ||
if (!importedMetadata.getTrackInfo().getTitle().isEmpty()) { | ||
updatedMetadata.refTrackInfo().setTitle( | ||
importedMetadata.getTrackInfo().getTitle()); | ||
} | ||
if (!importedMetadata.getTrackInfo().getTrackNumber().isEmpty()) { | ||
updatedMetadata.refTrackInfo().setTrackNumber( | ||
importedMetadata.getTrackInfo().getTrackNumber() | ||
); | ||
} | ||
if (!importedMetadata.getTrackInfo().getTrackTotal().isEmpty()) { | ||
updatedMetadata.refTrackInfo().setTrackTotal( | ||
importedMetadata.getTrackInfo().getTrackTotal() | ||
); | ||
} | ||
if (!importedMetadata.getTrackInfo().getYear().isEmpty()) { | ||
updatedMetadata.refTrackInfo().setYear( | ||
importedMetadata.getTrackInfo().getYear()); | ||
} | ||
if (!m_data.m_results[resultIndex]->getArtist().isEmpty()) { | ||
m_track->setArtist(m_data.m_results[resultIndex]->getArtist()); | ||
if (!importedMetadata.getAlbumInfo().getArtist().isEmpty()) { | ||
updatedMetadata.refAlbumInfo().setArtist( | ||
importedMetadata.getAlbumInfo().getArtist()); | ||
} | ||
if (!m_data.m_results[resultIndex]->getTitle().isEmpty()) { | ||
m_track->setTitle(m_data.m_results[resultIndex]->getTitle()); | ||
if (!importedMetadata.getAlbumInfo().getTitle().isEmpty()) { | ||
updatedMetadata.refAlbumInfo().setTitle( | ||
importedMetadata.getAlbumInfo().getTitle()); | ||
} | ||
if (!m_data.m_results[resultIndex]->getYear().isEmpty() && | ||
m_data.m_results[resultIndex]->getYear() != "0") { | ||
m_track->setYear(m_data.m_results[resultIndex]->getYear()); | ||
#if defined(__EXTRA_METADATA__) | ||
if (!importedMetadata.getTrackInfo().getMusicBrainzArtistId().isNull()) { | ||
updatedMetadata.refTrackInfo().setMusicBrainzArtistId( | ||
importedMetadata.getTrackInfo().getMusicBrainzArtistId() | ||
); | ||
} | ||
if (!m_data.m_results[resultIndex]->getTrackNumber().isEmpty() && | ||
m_data.m_results[resultIndex]->getTrackNumber() != "0") { | ||
m_track->setTrackNumber(m_data.m_results[resultIndex]->getTrackNumber()); | ||
if (!importedMetadata.getTrackInfo().getMusicBrainzRecordingId().isNull()) { | ||
updatedMetadata.refTrackInfo().setMusicBrainzRecordingId( | ||
importedMetadata.getTrackInfo().getMusicBrainzRecordingId() | ||
); | ||
} | ||
if (!importedMetadata.getTrackInfo().getMusicBrainzReleaseId().isNull()) { | ||
updatedMetadata.refTrackInfo().setMusicBrainzReleaseId( | ||
importedMetadata.getTrackInfo().getMusicBrainzReleaseId() | ||
); | ||
} | ||
if (!importedMetadata.getAlbumInfo().getMusicBrainzArtistId().isNull()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder how the artist Id compared to the string representation. I think we need to handle them at once. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the recording id and the title? I will not make up a custom correlation logic without any foundation. I can only offer to implement one of the following options:
If someone knows how to correlate the fields in a consistent manner, please do so. I refuse to do it, because I am not able to come up with a solution that is supposed to be "correct". |
||
updatedMetadata.refAlbumInfo().setMusicBrainzArtistId( | ||
importedMetadata.getAlbumInfo().getMusicBrainzArtistId() | ||
); | ||
} | ||
if (!importedMetadata.getAlbumInfo().getMusicBrainzReleaseId().isNull()) { | ||
updatedMetadata.refAlbumInfo().setMusicBrainzReleaseId( | ||
importedMetadata.getAlbumInfo().getMusicBrainzReleaseId()); | ||
} | ||
if (!importedMetadata.getAlbumInfo().getMusicBrainzReleaseGroupId().isNull()) { | ||
updatedMetadata.refAlbumInfo().setMusicBrainzReleaseGroupId( | ||
importedMetadata.getAlbumInfo().getMusicBrainzReleaseGroupId()); | ||
} | ||
#endif // __EXTRA_METADATA__ | ||
m_track->importMetadata(std::move(updatedMetadata)); | ||
} | ||
} | ||
|
||
|
@@ -147,13 +226,21 @@ void DlgTagFetcher::updateStack() { | |
results->clear(); | ||
|
||
addDivider(tr("Original tags"), results); | ||
addTrack(m_track, -1, results); | ||
addTrack(track2row(*m_track), -1, results); | ||
|
||
addDivider(tr("Suggested tags"), results); | ||
|
||
int trackIndex = 0; | ||
foreach (const TrackPointer track, m_data.m_results) { | ||
addTrack(track, trackIndex++, results); | ||
{ | ||
int trackIndex = 0; | ||
QSet<QStringList> trackRows; | ||
foreach (const TrackPointer track, m_data.m_results) { | ||
const auto trackRow = track2row(*track); | ||
// Ignore duplicate results | ||
if (!trackRows.contains(trackRow)) { | ||
trackRows.insert(trackRow); | ||
addTrack(trackRow, trackIndex, results); | ||
} | ||
++trackIndex; | ||
} | ||
} | ||
|
||
// Find the item that was selected last time | ||
|
@@ -167,17 +254,6 @@ void DlgTagFetcher::updateStack() { | |
} | ||
} | ||
|
||
void DlgTagFetcher::addTrack(const TrackPointer track, int resultIndex, | ||
QTreeWidget* parent) const { | ||
QStringList values; | ||
values << track->getTrackNumber() << track->getYear() << track->getTitle() | ||
<< track->getArtist() << track->getAlbum(); | ||
|
||
QTreeWidgetItem* item = new QTreeWidgetItem(parent, values); | ||
item->setData(0, Qt::UserRole, resultIndex); | ||
item->setData(0, Qt::TextAlignmentRole, Qt::AlignRight); | ||
} | ||
|
||
void DlgTagFetcher::addDivider(const QString& text, QTreeWidget* parent) const { | ||
QTreeWidgetItem* item = new QTreeWidgetItem(parent); | ||
item->setFirstColumnSpanned(true); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 2row? Track2MetadataList.
It look like the underlying issue is, that the resultAvailable signal returning tracks.
It would be easier to understand and is probably more performant if it will directly return a custom track object containing the results (a single row) only. Can this be TrackRelease?
The string list solution here draws the column sorting into the management code which is also subobtimal. I think we should at least name the indexes of the list.
Thinking about all of this ... can't we deduplicate the results earlyer just after receiving them.
A custom deduplicate code, working in the temporary track objects would also be a solution.
Ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated the dialog only as needed. I will not implements further improvements other than passing-through of
mixxx::musicbrainz::TrackRelease
as suggested.PS: Performance doesn't matter here. I only changed the signal types, because the status quo of using QObjects for this purpose was wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dialogue needs to be extended anyway in the future. Whoever will do this can improve the deduplication logic and replace the QStringList. The deduplication currently depends on the displayed columns that are actually displayed and therefore must be done here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The simplistic deduplication logic before is really displaced and the code is difficult to follow. Now everything is co-located on the display layer were it actually matters. It's not optimal, but without a rationale for deduplication this is the best we could do for now.