[PICARD-1174] Add an option to tolerate differences in track times

The option `ignore_track_duration_difference_under` can be set through Advanced options panel.
If old and new Length tag have a difference under this value, they are considered equal, and this isn't accounted as a track difference.
This commit is contained in:
Laurent Monin
2018-01-18 11:15:04 +01:00
parent 1457fb850b
commit d37555d3ed
4 changed files with 138 additions and 23 deletions

View File

@@ -96,18 +96,19 @@ class TagCounter(dict):
class TagDiff(object):
__slots__ = ("tag_names", "new", "orig", "status", "objects")
__slots__ = ("tag_names", "new", "orig", "status", "objects", "max_length_delta_ms")
def __init__(self):
def __init__(self, max_length_diff=2):
self.tag_names = []
self.new = TagCounter(self)
self.orig = TagCounter(self)
self.status = defaultdict(lambda: 0)
self.objects = 0
self.max_length_delta_ms = max_length_diff * 1000
def __tag_ne(self, tag, orig, new):
if tag == "~length":
return abs(float(orig) - float(new)) > 2000
return abs(float(orig) - float(new)) > self.max_length_delta_ms
else:
return orig != new
@@ -427,7 +428,7 @@ class MetadataBox(QtWidgets.QTableWidget):
if not (files or tracks):
return None
tag_diff = TagDiff()
tag_diff = TagDiff(max_length_diff=config.setting["ignore_track_duration_difference_under"])
orig_tags = tag_diff.orig
new_tags = tag_diff.new
# existing_tags are orig_tags that would not be overwritten by

View File

@@ -34,6 +34,7 @@ class AdvancedOptionsPage(OptionsPage):
config.TextOption("setting", "ignore_regex", ""),
config.BoolOption("setting", "ignore_hidden_files", False),
config.BoolOption("setting", "recursively_add_files", True),
config.IntOption("setting", "ignore_track_duration_difference_under", 2),
config.BoolOption("setting", "completeness_ignore_videos", False),
config.BoolOption("setting", "completeness_ignore_pregap", False),
config.BoolOption("setting", "completeness_ignore_data", False),
@@ -50,6 +51,7 @@ class AdvancedOptionsPage(OptionsPage):
self.ui.ignore_regex.setText(config.setting["ignore_regex"])
self.ui.ignore_hidden_files.setChecked(config.setting["ignore_hidden_files"])
self.ui.recursively_add_files.setChecked(config.setting["recursively_add_files"])
self.ui.ignore_track_duration_difference_under.setValue(config.setting["ignore_track_duration_difference_under"])
self.ui.completeness_ignore_videos.setChecked(config.setting["completeness_ignore_videos"])
self.ui.completeness_ignore_pregap.setChecked(config.setting["completeness_ignore_pregap"])
self.ui.completeness_ignore_data.setChecked(config.setting["completeness_ignore_data"])
@@ -59,6 +61,7 @@ class AdvancedOptionsPage(OptionsPage):
config.setting["ignore_regex"] = self.ui.ignore_regex.text()
config.setting["ignore_hidden_files"] = self.ui.ignore_hidden_files.isChecked()
config.setting["recursively_add_files"] = self.ui.recursively_add_files.isChecked()
config.setting["ignore_track_duration_difference_under"] = self.ui.ignore_track_duration_difference_under.value()
config.setting["completeness_ignore_videos"] = self.ui.completeness_ignore_videos.isChecked()
config.setting["completeness_ignore_pregap"] = self.ui.completeness_ignore_pregap.isChecked()
config.setting["completeness_ignore_data"] = self.ui.completeness_ignore_data.isChecked()

View File

@@ -16,22 +16,51 @@ class Ui_AdvancedOptionsPage(object):
self.gridlayout = QtWidgets.QGridLayout(self.groupBox)
self.gridlayout.setSpacing(2)
self.gridlayout.setObjectName("gridlayout")
self.recursively_add_files = QtWidgets.QCheckBox(self.groupBox)
self.recursively_add_files.setObjectName("recursively_add_files")
self.gridlayout.addWidget(self.recursively_add_files, 5, 0, 1, 1)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_track_duration_diff = QtWidgets.QLabel(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_track_duration_diff.sizePolicy().hasHeightForWidth())
self.label_track_duration_diff.setSizePolicy(sizePolicy)
self.label_track_duration_diff.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_track_duration_diff.setObjectName("label_track_duration_diff")
self.horizontalLayout.addWidget(self.label_track_duration_diff)
self.ignore_track_duration_difference_under = QtWidgets.QSpinBox(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.ignore_track_duration_difference_under.sizePolicy().hasHeightForWidth())
self.ignore_track_duration_difference_under.setSizePolicy(sizePolicy)
self.ignore_track_duration_difference_under.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows)
self.ignore_track_duration_difference_under.setAccelerated(True)
self.ignore_track_duration_difference_under.setSuffix("")
self.ignore_track_duration_difference_under.setMinimum(1)
self.ignore_track_duration_difference_under.setMaximum(7200)
self.ignore_track_duration_difference_under.setProperty("value", 2)
self.ignore_track_duration_difference_under.setObjectName("ignore_track_duration_difference_under")
self.horizontalLayout.addWidget(self.ignore_track_duration_difference_under)
spacerItem = QtWidgets.QSpacerItem(4000, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.gridlayout.addLayout(self.horizontalLayout, 6, 0, 2, 1)
self.label_ignore_regex = QtWidgets.QLabel(self.groupBox)
self.label_ignore_regex.setObjectName("label_ignore_regex")
self.gridlayout.addWidget(self.label_ignore_regex, 1, 0, 1, 1)
self.regex_error = QtWidgets.QLabel(self.groupBox)
self.regex_error.setText("")
self.regex_error.setObjectName("regex_error")
self.gridlayout.addWidget(self.regex_error, 3, 0, 1, 1)
self.label_ignore_regex = QtWidgets.QLabel(self.groupBox)
self.label_ignore_regex.setObjectName("label_ignore_regex")
self.gridlayout.addWidget(self.label_ignore_regex, 1, 0, 1, 1)
self.ignore_hidden_files = QtWidgets.QCheckBox(self.groupBox)
self.ignore_hidden_files.setObjectName("ignore_hidden_files")
self.gridlayout.addWidget(self.ignore_hidden_files, 4, 0, 1, 1)
self.ignore_regex = QtWidgets.QLineEdit(self.groupBox)
self.ignore_regex.setObjectName("ignore_regex")
self.gridlayout.addWidget(self.ignore_regex, 2, 0, 1, 1)
self.recursively_add_files = QtWidgets.QCheckBox(self.groupBox)
self.recursively_add_files.setObjectName("recursively_add_files")
self.gridlayout.addWidget(self.recursively_add_files, 5, 0, 1, 1)
self.vboxlayout.addWidget(self.groupBox)
self.groupBox_completeness = QtWidgets.QGroupBox(AdvancedOptionsPage)
self.groupBox_completeness.setObjectName("groupBox_completeness")
@@ -51,18 +80,26 @@ class Ui_AdvancedOptionsPage(object):
self.completeness_ignore_silence.setObjectName("completeness_ignore_silence")
self.verticalLayout_2.addWidget(self.completeness_ignore_silence)
self.vboxlayout.addWidget(self.groupBox_completeness)
spacerItem = QtWidgets.QSpacerItem(181, 21, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.vboxlayout.addItem(spacerItem)
spacerItem1 = QtWidgets.QSpacerItem(181, 21, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.vboxlayout.addItem(spacerItem1)
self.retranslateUi(AdvancedOptionsPage)
QtCore.QMetaObject.connectSlotsByName(AdvancedOptionsPage)
AdvancedOptionsPage.setTabOrder(self.ignore_regex, self.ignore_hidden_files)
AdvancedOptionsPage.setTabOrder(self.ignore_hidden_files, self.recursively_add_files)
AdvancedOptionsPage.setTabOrder(self.recursively_add_files, self.ignore_track_duration_difference_under)
AdvancedOptionsPage.setTabOrder(self.ignore_track_duration_difference_under, self.completeness_ignore_videos)
AdvancedOptionsPage.setTabOrder(self.completeness_ignore_videos, self.completeness_ignore_pregap)
AdvancedOptionsPage.setTabOrder(self.completeness_ignore_pregap, self.completeness_ignore_data)
AdvancedOptionsPage.setTabOrder(self.completeness_ignore_data, self.completeness_ignore_silence)
def retranslateUi(self, AdvancedOptionsPage):
_translate = QtCore.QCoreApplication.translate
self.groupBox.setTitle(_("Advanced options"))
self.recursively_add_files.setText(_("Recursively add files and folders from directory"))
self.label_track_duration_diff.setText(_("Ignore track duration difference under this number of seconds"))
self.label_ignore_regex.setText(_("Ignore file paths matching the following regular expression:"))
self.ignore_hidden_files.setText(_("Ignore hidden files"))
self.recursively_add_files.setText(_("Recursively add files and folders from directory"))
self.groupBox_completeness.setTitle(_("Ignore the following tracks when determining whether a release is complete"))
self.completeness_ignore_videos.setText(_("Video tracks"))
self.completeness_ignore_pregap.setText(_("Pregap tracks"))

View File

@@ -20,13 +20,80 @@
<property name="spacing">
<number>2</number>
</property>
<item row="3" column="0">
<widget class="QLabel" name="regex_error">
<item row="5" column="0">
<widget class="QCheckBox" name="recursively_add_files">
<property name="text">
<string/>
<string>Recursively add files and folders from directory</string>
</property>
</widget>
</item>
<item row="6" column="0" rowspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="label_track_duration_diff">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Ignore track duration difference under this number of seconds</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="ignore_track_duration_difference_under">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::UpDownArrows</enum>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>7200</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4000</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_ignore_regex">
<property name="text">
@@ -34,6 +101,13 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="regex_error">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="ignore_hidden_files">
<property name="text">
@@ -44,13 +118,6 @@
<item row="2" column="0">
<widget class="QLineEdit" name="ignore_regex"/>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="recursively_add_files">
<property name="text">
<string>Recursively add files and folders from directory</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -111,6 +178,13 @@
</widget>
<tabstops>
<tabstop>ignore_regex</tabstop>
<tabstop>ignore_hidden_files</tabstop>
<tabstop>recursively_add_files</tabstop>
<tabstop>ignore_track_duration_difference_under</tabstop>
<tabstop>completeness_ignore_videos</tabstop>
<tabstop>completeness_ignore_pregap</tabstop>
<tabstop>completeness_ignore_data</tabstop>
<tabstop>completeness_ignore_silence</tabstop>
</tabstops>
<resources/>
<connections/>