forked from openlp/openlp
Rename lots of variables and methods. Shorten some too long lines.
This commit is contained in:
parent
bbd491baa8
commit
2a16a6ebcb
@ -63,9 +63,9 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
``plugin``
|
``plugin``
|
||||||
The songs plugin.
|
The songs plugin.
|
||||||
"""
|
"""
|
||||||
self.duplicateSongList = []
|
self.duplicate_song_list = []
|
||||||
self.reviewCurrentCount = 0
|
self.review_current_count = 0
|
||||||
self.reviewTotalCount = 0
|
self.review_total_count = 0
|
||||||
OpenLPWizard.__init__(self, parent, plugin, u'duplicateSongRemovalWizard',
|
OpenLPWizard.__init__(self, parent, plugin, u'duplicateSongRemovalWizard',
|
||||||
u':/wizards/wizard_duplicateremoval.bmp', False)
|
u':/wizards/wizard_duplicateremoval.bmp', False)
|
||||||
|
|
||||||
@ -87,44 +87,46 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
Add song wizard specific pages.
|
Add song wizard specific pages.
|
||||||
"""
|
"""
|
||||||
#add custom pages
|
#add custom pages
|
||||||
self.searchingPage = QtGui.QWizardPage()
|
self.searching_page = QtGui.QWizardPage()
|
||||||
self.searchingPage.setObjectName(u'searchingPage')
|
self.searching_page.setObjectName(u'searching_page')
|
||||||
self.searchingVerticalLayout = QtGui.QVBoxLayout(self.searchingPage)
|
self.searching_vertical_layout = QtGui.QVBoxLayout(self.searching_page)
|
||||||
self.searchingVerticalLayout.setObjectName(u'searchingVerticalLayout')
|
self.searching_vertical_layout.setObjectName(u'searching_vertical_layout')
|
||||||
self.duplicateSearchProgressBar = QtGui.QProgressBar(self.searchingPage)
|
self.duplicate_search_progress_bar = QtGui.QProgressBar(self.searching_page)
|
||||||
self.duplicateSearchProgressBar.setObjectName(u'duplicateSearchProgressBar')
|
self.duplicate_search_progress_bar.setObjectName(u'duplicate_search_progress_bar')
|
||||||
self.duplicateSearchProgressBar.setFormat(WizardStrings.PercentSymbolFormat)
|
self.duplicate_search_progress_bar.setFormat(WizardStrings.PercentSymbolFormat)
|
||||||
self.searchingVerticalLayout.addWidget(self.duplicateSearchProgressBar)
|
self.searching_vertical_layout.addWidget(self.duplicate_search_progress_bar)
|
||||||
self.foundDuplicatesEdit = QtGui.QPlainTextEdit(self.searchingPage)
|
self.found_duplicates_edit = QtGui.QPlainTextEdit(self.searching_page)
|
||||||
self.foundDuplicatesEdit.setUndoRedoEnabled(False)
|
self.found_duplicates_edit.setUndoRedoEnabled(False)
|
||||||
self.foundDuplicatesEdit.setReadOnly(True)
|
self.found_duplicates_edit.setReadOnly(True)
|
||||||
self.foundDuplicatesEdit.setObjectName(u'foundDuplicatesEdit')
|
self.found_duplicates_edit.setObjectName(u'found_duplicates_edit')
|
||||||
self.searchingVerticalLayout.addWidget(self.foundDuplicatesEdit)
|
self.searching_vertical_layout.addWidget(self.found_duplicates_edit)
|
||||||
self.searchingPageId = self.addPage(self.searchingPage)
|
self.searching_page_id = self.addPage(self.searching_page)
|
||||||
self.reviewPage = QtGui.QWizardPage()
|
self.review_page = QtGui.QWizardPage()
|
||||||
self.reviewPage.setObjectName(u'reviewPage')
|
self.review_page.setObjectName(u'review_page')
|
||||||
self.reviewLayout = QtGui.QVBoxLayout(self.reviewPage)
|
self.review_layout = QtGui.QVBoxLayout(self.review_page)
|
||||||
self.reviewLayout.setObjectName(u'reviewLayout')
|
self.review_layout.setObjectName(u'review_layout')
|
||||||
self.songsHorizontalScrollArea = QtGui.QScrollArea(self.reviewPage)
|
self.songs_horizontal_scroll_area = QtGui.QScrollArea(self.review_page)
|
||||||
self.songsHorizontalScrollArea.setObjectName(u'songsHorizontalScrollArea')
|
self.songs_horizontal_scroll_area.setObjectName(u'songs_horizontal_scroll_area')
|
||||||
self.songsHorizontalScrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
self.songs_horizontal_scroll_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||||
self.songsHorizontalScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
self.songs_horizontal_scroll_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||||
self.songsHorizontalScrollArea.setFrameStyle(QtGui.QFrame.NoFrame)
|
self.songs_horizontal_scroll_area.setFrameStyle(QtGui.QFrame.NoFrame)
|
||||||
self.songsHorizontalScrollArea.setWidgetResizable(True)
|
self.songs_horizontal_scroll_area.setWidgetResizable(True)
|
||||||
self.songsHorizontalScrollArea.setStyleSheet(u'QScrollArea#songsHorizontalScrollArea {background-color:transparent;}')
|
self.songs_horizontal_scroll_area.setStyleSheet(
|
||||||
self.songsHorizontalSongsWidget = QtGui.QWidget(self.songsHorizontalScrollArea)
|
u'QScrollArea#songs_horizontal_scroll_area {background-color:transparent;}')
|
||||||
self.songsHorizontalSongsWidget.setObjectName(u'songsHorizontalSongsWidget')
|
self.songs_horizontal_songs_widget = QtGui.QWidget(self.songs_horizontal_scroll_area)
|
||||||
self.songsHorizontalSongsWidget.setStyleSheet(u'QWidget#songsHorizontalSongsWidget {background-color:transparent;}')
|
self.songs_horizontal_songs_widget.setObjectName(u'songs_horizontal_songs_widget')
|
||||||
self.songsHorizontalLayout = QtGui.QHBoxLayout(self.songsHorizontalSongsWidget)
|
self.songs_horizontal_songs_widget.setStyleSheet(
|
||||||
self.songsHorizontalLayout.setObjectName(u'songsHorizontalLayout')
|
u'QWidget#songs_horizontal_songs_widget {background-color:transparent;}')
|
||||||
self.songsHorizontalLayout.setSizeConstraint(QtGui.QLayout.SetMinAndMaxSize)
|
self.songs_horizontal_layout = QtGui.QHBoxLayout(self.songs_horizontal_songs_widget)
|
||||||
self.songsHorizontalScrollArea.setWidget(self.songsHorizontalSongsWidget)
|
self.songs_horizontal_layout.setObjectName(u'songs_horizontal_layout')
|
||||||
self.reviewLayout.addWidget(self.songsHorizontalScrollArea)
|
self.songs_horizontal_layout.setSizeConstraint(QtGui.QLayout.SetMinAndMaxSize)
|
||||||
self.reviewPageId = self.addPage(self.reviewPage)
|
self.songs_horizontal_scroll_area.setWidget(self.songs_horizontal_songs_widget)
|
||||||
|
self.review_layout.addWidget(self.songs_horizontal_scroll_area)
|
||||||
|
self.review_page_id = self.addPage(self.review_page)
|
||||||
#add a dummy page to the end, to prevent the finish button to appear and the next button do disappear on the
|
#add a dummy page to the end, to prevent the finish button to appear and the next button do disappear on the
|
||||||
#review page
|
#review page
|
||||||
self.dummyPage = QtGui.QWizardPage()
|
self.dummy_page = QtGui.QWizardPage()
|
||||||
self.dummyPageId = self.addPage(self.dummyPage)
|
self.dummy_page_id = self.addPage(self.dummy_page)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
"""
|
"""
|
||||||
@ -137,53 +139,54 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
u'This wizard will help you to remove duplicate songs from the song database. You will have a chance to '
|
u'This wizard will help you to remove duplicate songs from the song database. You will have a chance to '
|
||||||
u'review every potential duplicate song before it is deleted. So no songs will be deleted without your '
|
u'review every potential duplicate song before it is deleted. So no songs will be deleted without your '
|
||||||
u'explicit approval.'))
|
u'explicit approval.'))
|
||||||
self.searchingPage.setTitle(translate(u'Wizard', u'Searching for duplicate songs.'))
|
self.searching_page.setTitle(translate(u'Wizard', u'Searching for duplicate songs.'))
|
||||||
self.searchingPage.setSubTitle(translate(u'Wizard', u'The song database is searched for double songs.'))
|
self.searching_page.setSubTitle(translate(u'Wizard', u'The song database is searched for double songs.'))
|
||||||
self.updateReviewCounterText()
|
self.updateReviewCounterText()
|
||||||
self.reviewPage.setSubTitle(translate(u'Wizard',
|
self.review_page.setSubTitle(translate(u'Wizard',
|
||||||
u'Here you can decide which songs to remove and which ones to keep.'))
|
u'Here you can decide which songs to remove and which ones to keep.'))
|
||||||
|
|
||||||
def updateReviewCounterText(self):
|
def updateReviewCounterText(self):
|
||||||
"""
|
"""
|
||||||
Set the wizard review page header text.
|
Set the wizard review page header text.
|
||||||
"""
|
"""
|
||||||
self.reviewPage.setTitle(translate(u'Wizard', u'Review duplicate songs (%s/%s)') % \
|
self.review_page.setTitle(translate(u'Wizard', u'Review duplicate songs (%s/%s)') % \
|
||||||
(self.reviewCurrentCount, self.reviewTotalCount))
|
(self.review_current_count, self.review_total_count))
|
||||||
|
|
||||||
def customPageChanged(self, pageId):
|
def customPageChanged(self, page_id):
|
||||||
"""
|
"""
|
||||||
Called when changing the wizard page.
|
Called when changing the wizard page.
|
||||||
|
|
||||||
``pageId``
|
``page_id``
|
||||||
ID of the page the wizard changed to.
|
ID of the page the wizard changed to.
|
||||||
"""
|
"""
|
||||||
#hide back button
|
#hide back button
|
||||||
self.button(QtGui.QWizard.BackButton).hide()
|
self.button(QtGui.QWizard.BackButton).hide()
|
||||||
if pageId == self.searchingPageId:
|
if page_id == self.searching_page_id:
|
||||||
#search duplicate songs
|
#search duplicate songs
|
||||||
maxSongs = self.plugin.manager.get_object_count(Song)
|
max_songs = self.plugin.manager.get_object_count(Song)
|
||||||
if maxSongs == 0 or maxSongs == 1:
|
if max_songs == 0 or max_songs == 1:
|
||||||
self.duplicateSearchProgressBar.setMaximum(1)
|
self.duplicate_search_progress_bar.setMaximum(1)
|
||||||
self.duplicateSearchProgressBar.setValue(1)
|
self.duplicate_search_progress_bar.setValue(1)
|
||||||
self.notifyNoDuplicates()
|
self.notifyNoDuplicates()
|
||||||
return
|
return
|
||||||
# with x songs we have x*(x - 1) / 2 comparisons
|
# with x songs we have x*(x - 1) / 2 comparisons
|
||||||
maxProgressCount = maxSongs * (maxSongs - 1) / 2
|
max_progress_count = max_songs * (max_songs - 1) / 2
|
||||||
self.duplicateSearchProgressBar.setMaximum(maxProgressCount)
|
self.duplicate_search_progress_bar.setMaximum(max_progress_count)
|
||||||
songs = self.plugin.manager.get_all_objects(Song)
|
songs = self.plugin.manager.get_all_objects(Song)
|
||||||
for outerSongCounter in range(maxSongs - 1):
|
for outer_song_counter in range(max_songs - 1):
|
||||||
for innerSongCounter in range(outerSongCounter + 1, maxSongs):
|
for inner_song_counter in range(outer_song_counter + 1, max_songs):
|
||||||
doubleFinder = DuplicateSongFinder()
|
double_finder = DuplicateSongFinder()
|
||||||
if doubleFinder.songsProbablyEqual(songs[outerSongCounter], songs[innerSongCounter]):
|
if double_finder.songs_probably_equal(songs[outer_song_counter], songs[inner_song_counter]):
|
||||||
duplicateAdded = self.addDuplicatesToSongList(songs[outerSongCounter], songs[innerSongCounter])
|
duplicate_added = self.addDuplicatesToSongList(songs[outer_song_counter],
|
||||||
if duplicateAdded:
|
songs[inner_song_counter])
|
||||||
self.foundDuplicatesEdit.appendPlainText(songs[outerSongCounter].title + " = " +
|
if duplicate_added:
|
||||||
songs[innerSongCounter].title)
|
self.found_duplicates_edit.appendPlainText(songs[outer_song_counter].title + " = " +
|
||||||
self.duplicateSearchProgressBar.setValue(self.duplicateSearchProgressBar.value() + 1)
|
songs[inner_song_counter].title)
|
||||||
self.reviewTotalCount = len(self.duplicateSongList)
|
self.duplicate_search_progress_bar.setValue(self.duplicate_search_progress_bar.value() + 1)
|
||||||
if self.reviewTotalCount == 0:
|
self.review_total_count = len(self.duplicate_song_list)
|
||||||
|
if self.review_total_count == 0:
|
||||||
self.notifyNoDuplicates()
|
self.notifyNoDuplicates()
|
||||||
elif pageId == self.reviewPageId:
|
elif page_id == self.review_page_id:
|
||||||
self.processCurrentDuplicateEntry()
|
self.processCurrentDuplicateEntry()
|
||||||
|
|
||||||
def notifyNoDuplicates(self):
|
def notifyNoDuplicates(self):
|
||||||
@ -198,7 +201,7 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
|
||||||
|
|
||||||
|
|
||||||
def addDuplicatesToSongList(self, searchSong, duplicateSong):
|
def addDuplicatesToSongList(self, search_song, duplicate_song):
|
||||||
"""
|
"""
|
||||||
Inserts a song duplicate (two similar songs) to the duplicate song list.
|
Inserts a song duplicate (two similar songs) to the duplicate song list.
|
||||||
If one of the two songs is already part of the duplicate song list,
|
If one of the two songs is already part of the duplicate song list,
|
||||||
@ -206,34 +209,34 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
Returns True if at least one of the songs was added, False if both were already
|
Returns True if at least one of the songs was added, False if both were already
|
||||||
member of a group.
|
member of a group.
|
||||||
|
|
||||||
``searchSong``
|
``search_song``
|
||||||
The song we searched the duplicate for.
|
The song we searched the duplicate for.
|
||||||
|
|
||||||
``duplicateSong``
|
``duplicate_song``
|
||||||
The duplicate song.
|
The duplicate song.
|
||||||
"""
|
"""
|
||||||
duplicateGroupFound = False
|
duplicate_group_found = False
|
||||||
duplicateAdded = False
|
duplicate_added = False
|
||||||
for duplicateGroup in self.duplicateSongList:
|
for duplicate_group in self.duplicate_song_list:
|
||||||
#skip the first song in the duplicate lists, since the first one has to be an earlier song
|
#skip the first song in the duplicate lists, since the first one has to be an earlier song
|
||||||
if searchSong in duplicateGroup and not duplicateSong in duplicateGroup:
|
if search_song in duplicate_group and not duplicate_song in duplicate_group:
|
||||||
duplicateGroup.append(duplicateSong)
|
duplicate_group.append(duplicate_song)
|
||||||
duplicateGroupFound = True
|
duplicate_group_found = True
|
||||||
duplicateAdded = True
|
duplicate_added = True
|
||||||
break
|
break
|
||||||
elif not searchSong in duplicateGroup and duplicateSong in duplicateGroup:
|
elif not search_song in duplicate_group and duplicate_song in duplicate_group:
|
||||||
duplicateGroup.append(searchSong)
|
duplicate_group.append(search_song)
|
||||||
duplicateGroupFound = True
|
duplicate_group_found = True
|
||||||
duplicateAdded = True
|
duplicate_added = True
|
||||||
break
|
break
|
||||||
elif searchSong in duplicateGroup and duplicateSong in duplicateGroup:
|
elif search_song in duplicate_group and duplicate_song in duplicate_group:
|
||||||
duplicateGroupFound = True
|
duplicate_group_found = True
|
||||||
duplicateAdded = False
|
duplicate_added = False
|
||||||
break
|
break
|
||||||
if not duplicateGroupFound:
|
if not duplicate_group_found:
|
||||||
self.duplicateSongList.append([searchSong, duplicateSong])
|
self.duplicate_song_list.append([search_song, duplicate_song])
|
||||||
duplicateAdded = True
|
duplicate_added = True
|
||||||
return duplicateAdded
|
return duplicate_added
|
||||||
|
|
||||||
def onWizardExit(self):
|
def onWizardExit(self):
|
||||||
"""
|
"""
|
||||||
@ -247,36 +250,36 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
Set default form values for the song import wizard.
|
Set default form values for the song import wizard.
|
||||||
"""
|
"""
|
||||||
self.restart()
|
self.restart()
|
||||||
self.duplicateSearchProgressBar.setValue(0)
|
self.duplicate_search_progress_bar.setValue(0)
|
||||||
self.foundDuplicatesEdit.clear()
|
self.found_duplicates_edit.clear()
|
||||||
|
|
||||||
def validateCurrentPage(self):
|
def validateCurrentPage(self):
|
||||||
"""
|
"""
|
||||||
Controls whether we should switch to the next wizard page. This method loops
|
Controls whether we should switch to the next wizard page. This method loops
|
||||||
on the review page as long as there are more song duplicates to review.
|
on the review page as long as there are more song duplicates to review.
|
||||||
"""
|
"""
|
||||||
if self.currentId() == self.reviewPageId:
|
if self.currentId() == self.review_page_id:
|
||||||
#as long as it's not the last duplicate list entry we revisit the review page
|
#as long as it's not the last duplicate list entry we revisit the review page
|
||||||
if len(self.duplicateSongList) == 1:
|
if len(self.duplicate_song_list) == 1:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.proceedToNextReview()
|
self.proceedToNextReview()
|
||||||
return False
|
return False
|
||||||
return OpenLPWizard.validateCurrentPage(self)
|
return OpenLPWizard.validateCurrentPage(self)
|
||||||
|
|
||||||
def removeButtonClicked(self, songReviewWidget):
|
def removeButtonClicked(self, song_review_widget):
|
||||||
"""
|
"""
|
||||||
Removes a song from the database, removes the GUI element representing the
|
Removes a song from the database, removes the GUI element representing the
|
||||||
song on the review page, and disable the remove button if only one duplicate
|
song on the review page, and disable the remove button if only one duplicate
|
||||||
is left.
|
is left.
|
||||||
|
|
||||||
``songReviewWidget``
|
``song_review_widget``
|
||||||
The SongReviewWidget whose song we should delete.
|
The SongReviewWidget whose song we should delete.
|
||||||
"""
|
"""
|
||||||
#remove song from duplicate song list
|
#remove song from duplicate song list
|
||||||
self.duplicateSongList[-1].remove(songReviewWidget.song)
|
self.duplicate_song_list[-1].remove(song_review_widget.song)
|
||||||
#remove song
|
#remove song
|
||||||
item_id = songReviewWidget.song.id
|
item_id = song_review_widget.song.id
|
||||||
media_files = self.plugin.manager.get_all_objects(MediaFile,
|
media_files = self.plugin.manager.get_all_objects(MediaFile,
|
||||||
MediaFile.song_id == item_id)
|
MediaFile.song_id == item_id)
|
||||||
for media_file in media_files:
|
for media_file in media_files:
|
||||||
@ -294,31 +297,31 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
log.exception(u'Could not remove directory: %s', save_path)
|
log.exception(u'Could not remove directory: %s', save_path)
|
||||||
self.plugin.manager.delete_object(Song, item_id)
|
self.plugin.manager.delete_object(Song, item_id)
|
||||||
# remove GUI elements
|
# remove GUI elements
|
||||||
self.songsHorizontalLayout.removeWidget(songReviewWidget)
|
self.songs_horizontal_layout.removeWidget(song_review_widget)
|
||||||
songReviewWidget.setParent(None)
|
song_review_widget.setParent(None)
|
||||||
# check if we only have one duplicate left
|
# check if we only have one duplicate left
|
||||||
# 4 stretches + 1 SongReviewWidget = 5
|
# 4 stretches + 1 SongReviewWidget = 5
|
||||||
# the SongReviewWidget is then at position 2
|
# the SongReviewWidget is then at position 2
|
||||||
if len(self.duplicateSongList[-1]) == 1:
|
if len(self.duplicate_song_list[-1]) == 1:
|
||||||
self.songsHorizontalLayout.itemAt(2).widget().songRemoveButton.setEnabled(False)
|
self.songs_horizontal_layout.itemAt(2).widget().song_remove_button.setEnabled(False)
|
||||||
|
|
||||||
def proceedToNextReview(self):
|
def proceedToNextReview(self):
|
||||||
"""
|
"""
|
||||||
Removes the previous review UI elements and calls processCurrentDuplicateEntry.
|
Removes the previous review UI elements and calls processCurrentDuplicateEntry.
|
||||||
"""
|
"""
|
||||||
#remove last duplicate group
|
#remove last duplicate group
|
||||||
self.duplicateSongList.pop()
|
self.duplicate_song_list.pop()
|
||||||
# remove all previous elements
|
# remove all previous elements
|
||||||
for i in reversed(range(self.songsHorizontalLayout.count())):
|
for i in reversed(range(self.songs_horizontal_layout.count())):
|
||||||
item = self.songsHorizontalLayout.itemAt(i)
|
item = self.songs_horizontal_layout.itemAt(i)
|
||||||
if isinstance(item, QtGui.QWidgetItem):
|
if isinstance(item, QtGui.QWidgetItem):
|
||||||
# the order is important here, if the .setParent(None) call is done before the .removeItem() call, a
|
# The order is important here, if the .setParent(None) call is done
|
||||||
# segfault occurs
|
# before the .removeItem() call, a segfault occurs.
|
||||||
widget = item.widget()
|
widget = item.widget()
|
||||||
self.songsHorizontalLayout.removeItem(item)
|
self.songs_horizontal_layout.removeItem(item)
|
||||||
widget.setParent(None)
|
widget.setParent(None)
|
||||||
else:
|
else:
|
||||||
self.songsHorizontalLayout.removeItem(item)
|
self.songs_horizontal_layout.removeItem(item)
|
||||||
#process next set of duplicates
|
#process next set of duplicates
|
||||||
self.processCurrentDuplicateEntry()
|
self.processCurrentDuplicateEntry()
|
||||||
|
|
||||||
@ -329,23 +332,23 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||||||
duplicate song group, hide the "next" button and show the "finish" button.
|
duplicate song group, hide the "next" button and show the "finish" button.
|
||||||
"""
|
"""
|
||||||
# update counter
|
# update counter
|
||||||
self.reviewCurrentCount = self.reviewTotalCount - (len(self.duplicateSongList) - 1)
|
self.review_current_count = self.review_total_count - (len(self.duplicate_song_list) - 1)
|
||||||
self.updateReviewCounterText()
|
self.updateReviewCounterText()
|
||||||
# add song elements to the UI
|
# add song elements to the UI
|
||||||
if len(self.duplicateSongList) > 0:
|
if len(self.duplicate_song_list) > 0:
|
||||||
# a stretch doesn't seem to stretch endlessly, so I add two to get enough stetch for 1400x1050
|
# a stretch doesn't seem to stretch endlessly, so I add two to get enough stetch for 1400x1050
|
||||||
self.songsHorizontalLayout.addStretch()
|
self.songs_horizontal_layout.addStretch()
|
||||||
self.songsHorizontalLayout.addStretch()
|
self.songs_horizontal_layout.addStretch()
|
||||||
for duplicate in self.duplicateSongList[-1]:
|
for duplicate in self.duplicate_song_list[-1]:
|
||||||
songReviewWidget = SongReviewWidget(self.reviewPage, duplicate)
|
song_review_widget = SongReviewWidget(self.review_page, duplicate)
|
||||||
QtCore.QObject.connect(songReviewWidget,
|
QtCore.QObject.connect(song_review_widget,
|
||||||
QtCore.SIGNAL(u'songRemoveButtonClicked(PyQt_PyObject)'),
|
QtCore.SIGNAL(u'songRemoveButtonClicked(PyQt_PyObject)'),
|
||||||
self.removeButtonClicked)
|
self.removeButtonClicked)
|
||||||
self.songsHorizontalLayout.addWidget(songReviewWidget)
|
self.songs_horizontal_layout.addWidget(song_review_widget)
|
||||||
self.songsHorizontalLayout.addStretch()
|
self.songs_horizontal_layout.addStretch()
|
||||||
self.songsHorizontalLayout.addStretch()
|
self.songs_horizontal_layout.addStretch()
|
||||||
#change next button to finish button on last review
|
#change next button to finish button on last review
|
||||||
if len(self.duplicateSongList) == 1:
|
if len(self.duplicate_song_list) == 1:
|
||||||
self.button(QtGui.QWizard.FinishButton).show()
|
self.button(QtGui.QWizard.FinishButton).show()
|
||||||
self.button(QtGui.QWizard.FinishButton).setEnabled(True)
|
self.button(QtGui.QWizard.FinishButton).setEnabled(True)
|
||||||
self.button(QtGui.QWizard.NextButton).hide()
|
self.button(QtGui.QWizard.NextButton).hide()
|
||||||
@ -370,119 +373,119 @@ class SongReviewWidget(QtGui.QWidget):
|
|||||||
self.song = song
|
self.song = song
|
||||||
self.setupUi()
|
self.setupUi()
|
||||||
self.retranslateUi()
|
self.retranslateUi()
|
||||||
QtCore.QObject.connect(self.songRemoveButton, QtCore.SIGNAL(u'clicked()'), self.onRemoveButtonClicked)
|
QtCore.QObject.connect(self.song_remove_button, QtCore.SIGNAL(u'clicked()'), self.onRemoveButtonClicked)
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
self.songVerticalLayout = QtGui.QVBoxLayout(self)
|
self.song_vertical_layout = QtGui.QVBoxLayout(self)
|
||||||
self.songVerticalLayout.setObjectName(u'songVerticalLayout')
|
self.song_vertical_layout.setObjectName(u'song_vertical_layout')
|
||||||
self.songGroupBox = QtGui.QGroupBox(self)
|
self.song_group_box = QtGui.QGroupBox(self)
|
||||||
self.songGroupBox.setObjectName(u'songGroupBox')
|
self.song_group_box.setObjectName(u'song_group_box')
|
||||||
self.songGroupBox.setMinimumWidth(300)
|
self.song_group_box.setMinimumWidth(300)
|
||||||
self.songGroupBox.setMaximumWidth(300)
|
self.song_group_box.setMaximumWidth(300)
|
||||||
self.songGroupBoxLayout = QtGui.QVBoxLayout(self.songGroupBox)
|
self.song_group_box_layout = QtGui.QVBoxLayout(self.song_group_box)
|
||||||
self.songGroupBoxLayout.setObjectName(u'songGroupBoxLayout')
|
self.song_group_box_layout.setObjectName(u'song_group_box_layout')
|
||||||
self.songInfoFormLayout = QtGui.QFormLayout()
|
self.song_info_form_layout = QtGui.QFormLayout()
|
||||||
self.songInfoFormLayout.setObjectName(u'songInfoFormLayout')
|
self.song_info_form_layout.setObjectName(u'song_info_form_layout')
|
||||||
#title
|
#title
|
||||||
self.songTitleLabel = QtGui.QLabel(self)
|
self.song_title_label = QtGui.QLabel(self)
|
||||||
self.songTitleLabel.setObjectName(u'songTitleLabel')
|
self.song_title_label.setObjectName(u'song_title_label')
|
||||||
self.songInfoFormLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.songTitleLabel)
|
self.song_info_form_layout.setWidget(0, QtGui.QFormLayout.LabelRole, self.song_title_label)
|
||||||
self.songTitleContent = QtGui.QLabel(self)
|
self.song_title_content = QtGui.QLabel(self)
|
||||||
self.songTitleContent.setObjectName(u'songTitleContent')
|
self.song_title_content.setObjectName(u'song_title_content')
|
||||||
self.songTitleContent.setText(self.song.title)
|
self.song_title_content.setText(self.song.title)
|
||||||
self.songTitleContent.setWordWrap(True)
|
self.song_title_content.setWordWrap(True)
|
||||||
self.songInfoFormLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.songTitleContent)
|
self.song_info_form_layout.setWidget(0, QtGui.QFormLayout.FieldRole, self.song_title_content)
|
||||||
#alternate title
|
#alternate title
|
||||||
self.songAlternateTitleLabel = QtGui.QLabel(self)
|
self.song_alternate_title_label = QtGui.QLabel(self)
|
||||||
self.songAlternateTitleLabel.setObjectName(u'songAlternateTitleLabel')
|
self.song_alternate_title_label.setObjectName(u'song_alternate_title_label')
|
||||||
self.songInfoFormLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.songAlternateTitleLabel)
|
self.song_info_form_layout.setWidget(1, QtGui.QFormLayout.LabelRole, self.song_alternate_title_label)
|
||||||
self.songAlternateTitleContent = QtGui.QLabel(self)
|
self.song_alternate_title_content = QtGui.QLabel(self)
|
||||||
self.songAlternateTitleContent.setObjectName(u'songAlternateTitleContent')
|
self.song_alternate_title_content.setObjectName(u'song_alternate_title_content')
|
||||||
self.songAlternateTitleContent.setText(self.song.alternate_title)
|
self.song_alternate_title_content.setText(self.song.alternate_title)
|
||||||
self.songAlternateTitleContent.setWordWrap(True)
|
self.song_alternate_title_content.setWordWrap(True)
|
||||||
self.songInfoFormLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.songAlternateTitleContent)
|
self.song_info_form_layout.setWidget(1, QtGui.QFormLayout.FieldRole, self.song_alternate_title_content)
|
||||||
#CCLI number
|
#CCLI number
|
||||||
self.songCCLINumberLabel = QtGui.QLabel(self)
|
self.song_ccli_number_label = QtGui.QLabel(self)
|
||||||
self.songCCLINumberLabel.setObjectName(u'songCCLINumberLabel')
|
self.song_ccli_number_label.setObjectName(u'song_ccli_number_label')
|
||||||
self.songInfoFormLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.songCCLINumberLabel)
|
self.song_info_form_layout.setWidget(2, QtGui.QFormLayout.LabelRole, self.song_ccli_number_label)
|
||||||
self.songCCLINumberContent = QtGui.QLabel(self)
|
self.song_ccli_number_content = QtGui.QLabel(self)
|
||||||
self.songCCLINumberContent.setObjectName(u'songCCLINumberContent')
|
self.song_ccli_number_content.setObjectName(u'song_ccli_number_content')
|
||||||
self.songCCLINumberContent.setText(self.song.ccli_number)
|
self.song_ccli_number_content.setText(self.song.ccli_number)
|
||||||
self.songCCLINumberContent.setWordWrap(True)
|
self.song_ccli_number_content.setWordWrap(True)
|
||||||
self.songInfoFormLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.songCCLINumberContent)
|
self.song_info_form_layout.setWidget(2, QtGui.QFormLayout.FieldRole, self.song_ccli_number_content)
|
||||||
#copyright
|
#copyright
|
||||||
self.songCopyrightLabel = QtGui.QLabel(self)
|
self.song_copyright_label = QtGui.QLabel(self)
|
||||||
self.songCopyrightLabel.setObjectName(u'songCopyrightLabel')
|
self.song_copyright_label.setObjectName(u'song_copyright_label')
|
||||||
self.songInfoFormLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.songCopyrightLabel)
|
self.song_info_form_layout.setWidget(3, QtGui.QFormLayout.LabelRole, self.song_copyright_label)
|
||||||
self.songCopyrightContent = QtGui.QLabel(self)
|
self.song_copyright_content = QtGui.QLabel(self)
|
||||||
self.songCopyrightContent.setObjectName(u'songCopyrightContent')
|
self.song_copyright_content.setObjectName(u'song_copyright_content')
|
||||||
self.songCopyrightContent.setWordWrap(True)
|
self.song_copyright_content.setWordWrap(True)
|
||||||
self.songCopyrightContent.setText(self.song.copyright)
|
self.song_copyright_content.setText(self.song.copyright)
|
||||||
self.songInfoFormLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.songCopyrightContent)
|
self.song_info_form_layout.setWidget(3, QtGui.QFormLayout.FieldRole, self.song_copyright_content)
|
||||||
#comments
|
#comments
|
||||||
self.songCommentsLabel = QtGui.QLabel(self)
|
self.song_comments_label = QtGui.QLabel(self)
|
||||||
self.songCommentsLabel.setObjectName(u'songCommentsLabel')
|
self.song_comments_label.setObjectName(u'song_comments_label')
|
||||||
self.songInfoFormLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.songCommentsLabel)
|
self.song_info_form_layout.setWidget(4, QtGui.QFormLayout.LabelRole, self.song_comments_label)
|
||||||
self.songCommentsContent = QtGui.QLabel(self)
|
self.song_comments_content = QtGui.QLabel(self)
|
||||||
self.songCommentsContent.setObjectName(u'songCommentsContent')
|
self.song_comments_content.setObjectName(u'song_comments_content')
|
||||||
self.songCommentsContent.setText(self.song.comments)
|
self.song_comments_content.setText(self.song.comments)
|
||||||
self.songCommentsContent.setWordWrap(True)
|
self.song_comments_content.setWordWrap(True)
|
||||||
self.songInfoFormLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.songCommentsContent)
|
self.song_info_form_layout.setWidget(4, QtGui.QFormLayout.FieldRole, self.song_comments_content)
|
||||||
#authors
|
#authors
|
||||||
self.songAuthorsLabel = QtGui.QLabel(self)
|
self.song_authors_label = QtGui.QLabel(self)
|
||||||
self.songAuthorsLabel.setObjectName(u'songAuthorsLabel')
|
self.song_authors_label.setObjectName(u'song_authors_label')
|
||||||
self.songInfoFormLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.songAuthorsLabel)
|
self.song_info_form_layout.setWidget(5, QtGui.QFormLayout.LabelRole, self.song_authors_label)
|
||||||
self.songAuthorsContent = QtGui.QLabel(self)
|
self.song_authors_content = QtGui.QLabel(self)
|
||||||
self.songAuthorsContent.setObjectName(u'songAuthorsContent')
|
self.song_authors_content.setObjectName(u'song_authors_content')
|
||||||
self.songAuthorsContent.setWordWrap(True)
|
self.song_authors_content.setWordWrap(True)
|
||||||
authorsText = u''
|
authors_text = u''
|
||||||
for author in self.song.authors:
|
for author in self.song.authors:
|
||||||
authorsText += author.display_name + ', '
|
authors_text += author.display_name + ', '
|
||||||
if authorsText:
|
if authors_text:
|
||||||
authorsText = authorsText[:-2]
|
authors_text = authors_text[:-2]
|
||||||
self.songAuthorsContent.setText(authorsText)
|
self.song_authors_content.setText(authors_text)
|
||||||
self.songInfoFormLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.songAuthorsContent)
|
self.song_info_form_layout.setWidget(5, QtGui.QFormLayout.FieldRole, self.song_authors_content)
|
||||||
#verse order
|
#verse order
|
||||||
self.songVerseOrderLabel = QtGui.QLabel(self)
|
self.song_verse_order_label = QtGui.QLabel(self)
|
||||||
self.songVerseOrderLabel.setObjectName(u'songVerseOrderLabel')
|
self.song_verse_order_label.setObjectName(u'song_verse_order_label')
|
||||||
self.songInfoFormLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.songVerseOrderLabel)
|
self.song_info_form_layout.setWidget(6, QtGui.QFormLayout.LabelRole, self.song_verse_order_label)
|
||||||
self.songVerseOrderContent = QtGui.QLabel(self)
|
self.song_verse_order_content = QtGui.QLabel(self)
|
||||||
self.songVerseOrderContent.setObjectName(u'songVerseOrderContent')
|
self.song_verse_order_content.setObjectName(u'song_verse_order_content')
|
||||||
self.songVerseOrderContent.setText(self.song.verse_order)
|
self.song_verse_order_content.setText(self.song.verse_order)
|
||||||
self.songVerseOrderContent.setWordWrap(True)
|
self.song_verse_order_content.setWordWrap(True)
|
||||||
self.songInfoFormLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.songVerseOrderContent)
|
self.song_info_form_layout.setWidget(6, QtGui.QFormLayout.FieldRole, self.song_verse_order_content)
|
||||||
#verses
|
#verses
|
||||||
self.songGroupBoxLayout.addLayout(self.songInfoFormLayout)
|
self.song_group_box_layout.addLayout(self.song_info_form_layout)
|
||||||
self.songInfoVerseGroupBox = QtGui.QGroupBox(self.songGroupBox)
|
self.song_info_verse_group_box = QtGui.QGroupBox(self.song_group_box)
|
||||||
self.songInfoVerseGroupBox.setObjectName(u'songInfoVerseGroupBox')
|
self.song_info_verse_group_box.setObjectName(u'song_info_verse_group_box')
|
||||||
self.songInfoVerseGroupBoxLayout = QtGui.QFormLayout(self.songInfoVerseGroupBox)
|
self.song_info_verse_group_box_layout = QtGui.QFormLayout(self.song_info_verse_group_box)
|
||||||
songXml = SongXML()
|
song_xml = SongXML()
|
||||||
verses = songXml.get_verses(self.song.lyrics)
|
verses = song_xml.get_verses(self.song.lyrics)
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
verseMarker = verse[0]['type'] + verse[0]['label']
|
verse_marker = verse[0]['type'] + verse[0]['label']
|
||||||
verseLabel = QtGui.QLabel(self.songInfoVerseGroupBox)
|
verse_label = QtGui.QLabel(self.song_info_verse_group_box)
|
||||||
verseLabel.setText(verse[1])
|
verse_label.setText(verse[1])
|
||||||
verseLabel.setWordWrap(True)
|
verse_label.setWordWrap(True)
|
||||||
self.songInfoVerseGroupBoxLayout.addRow(verseMarker, verseLabel)
|
self.song_info_verse_group_box_layout.addRow(verse_marker, verse_label)
|
||||||
self.songGroupBoxLayout.addWidget(self.songInfoVerseGroupBox)
|
self.song_group_box_layout.addWidget(self.song_info_verse_group_box)
|
||||||
self.songGroupBoxLayout.addStretch()
|
self.song_group_box_layout.addStretch()
|
||||||
self.songVerticalLayout.addWidget(self.songGroupBox)
|
self.song_vertical_layout.addWidget(self.song_group_box)
|
||||||
self.songRemoveButton = QtGui.QPushButton(self)
|
self.song_remove_button = QtGui.QPushButton(self)
|
||||||
self.songRemoveButton.setObjectName(u'songRemoveButton')
|
self.song_remove_button.setObjectName(u'song_remove_button')
|
||||||
self.songRemoveButton.setIcon(build_icon(u':/songs/song_delete.png'))
|
self.song_remove_button.setIcon(build_icon(u':/songs/song_delete.png'))
|
||||||
self.songRemoveButton.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
self.song_remove_button.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||||
self.songVerticalLayout.addWidget(self.songRemoveButton, alignment = QtCore.Qt.AlignHCenter)
|
self.song_vertical_layout.addWidget(self.song_remove_button, alignment = QtCore.Qt.AlignHCenter)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.songRemoveButton.setText(u'Remove')
|
self.song_remove_button.setText(u'Remove')
|
||||||
self.songTitleLabel.setText(u'Title:')
|
self.song_title_label.setText(u'Title:')
|
||||||
self.songAlternateTitleLabel.setText(u'Alternate Title:')
|
self.song_alternate_title_label.setText(u'Alternate Title:')
|
||||||
self.songCCLINumberLabel.setText(u'CCLI Number:')
|
self.song_ccli_number_label.setText(u'CCLI Number:')
|
||||||
self.songVerseOrderLabel.setText(u'Verse Order:')
|
self.song_verse_order_label.setText(u'Verse Order:')
|
||||||
self.songCopyrightLabel.setText(u'Copyright:')
|
self.song_copyright_label.setText(u'Copyright:')
|
||||||
self.songCommentsLabel.setText(u'Comments:')
|
self.song_comments_label.setText(u'Comments:')
|
||||||
self.songAuthorsLabel.setText(u'Authors:')
|
self.song_authors_label.setText(u'Authors:')
|
||||||
self.songInfoVerseGroupBox.setTitle(u'Verses')
|
self.song_info_verse_group_box.setTitle(u'Verses')
|
||||||
|
|
||||||
def onRemoveButtonClicked(self):
|
def onRemoveButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
|
@ -38,23 +38,23 @@ class DuplicateSongFinder(object):
|
|||||||
The algorithm is based on the diff algorithm.
|
The algorithm is based on the diff algorithm.
|
||||||
First a diffset is calculated for two songs.
|
First a diffset is calculated for two songs.
|
||||||
To compensate for typos all differences that are smaller than a
|
To compensate for typos all differences that are smaller than a
|
||||||
limit (<maxTypoSize) and are surrounded by larger equal blocks
|
limit (<max_typo_size) and are surrounded by larger equal blocks
|
||||||
(>minFragmentSize) are removed and the surrounding equal parts are merged.
|
(>min_fragment_size) are removed and the surrounding equal parts are merged.
|
||||||
Finally two conditions can qualify a song tuple to be a duplicate:
|
Finally two conditions can qualify a song tuple to be a duplicate:
|
||||||
1. There is a block of equal content that is at least minBlockSize large.
|
1. There is a block of equal content that is at least min_block_size large.
|
||||||
This condition should hit for all larger songs that have a long enough
|
This condition should hit for all larger songs that have a long enough
|
||||||
equal part. Even if only one verse is equal this condition should still hit.
|
equal part. Even if only one verse is equal this condition should still hit.
|
||||||
2. Two thirds of the smaller song is contained in the larger song.
|
2. Two thirds of the smaller song is contained in the larger song.
|
||||||
This condition should hit if one of the two songs (or both) is small (smaller
|
This condition should hit if one of the two songs (or both) is small (smaller
|
||||||
than the minBlockSize), but most of the song is contained in the other song.
|
than the min_block_size), but most of the song is contained in the other song.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.minFragmentSize = 5
|
self.min_fragment_size = 5
|
||||||
self.minBlockSize = 70
|
self.min_block_size = 70
|
||||||
self.maxTypoSize = 3
|
self.max_typo_size = 3
|
||||||
|
|
||||||
def songsProbablyEqual(self, song1, song2):
|
def songs_probably_equal(self, song1, song2):
|
||||||
"""
|
"""
|
||||||
Calculate and return whether two songs are probably equal.
|
Calculate and return whether two songs are probably equal.
|
||||||
|
|
||||||
@ -72,15 +72,15 @@ class DuplicateSongFinder(object):
|
|||||||
large = song1.search_lyrics
|
large = song1.search_lyrics
|
||||||
differ = difflib.SequenceMatcher(a=large, b=small)
|
differ = difflib.SequenceMatcher(a=large, b=small)
|
||||||
diff_tuples = differ.get_opcodes()
|
diff_tuples = differ.get_opcodes()
|
||||||
diff_no_typos = self.__removeTypos(diff_tuples)
|
diff_no_typos = self.__remove_typos(diff_tuples)
|
||||||
#print(diff_no_typos)
|
#print(diff_no_typos)
|
||||||
if self.__lengthOfEqualBlocks(diff_no_typos) >= self.minBlockSize or \
|
if self.__length_of_equal_blocks(diff_no_typos) >= self.min_block_size or \
|
||||||
self.__lengthOfLongestEqualBlock(diff_no_typos) > len(small) * 2 / 3:
|
self.__length_of_longest_equal_block(diff_no_typos) > len(small) * 2 / 3:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __opLength(self, opcode):
|
def __op_length(self, opcode):
|
||||||
"""
|
"""
|
||||||
Return the length of a given difference.
|
Return the length of a given difference.
|
||||||
|
|
||||||
@ -89,57 +89,57 @@ class DuplicateSongFinder(object):
|
|||||||
"""
|
"""
|
||||||
return max(opcode[2] - opcode[1], opcode[4] - opcode[3])
|
return max(opcode[2] - opcode[1], opcode[4] - opcode[3])
|
||||||
|
|
||||||
def __removeTypos(self, diff):
|
def __remove_typos(self, diff):
|
||||||
"""
|
"""
|
||||||
Remove typos from a diff set. A typo is a small difference (<maxTypoSize)
|
Remove typos from a diff set. A typo is a small difference (<max_typo_size)
|
||||||
surrounded by larger equal passages (>minFragmentSize).
|
surrounded by larger equal passages (>min_fragment_size).
|
||||||
|
|
||||||
``diff``
|
``diff``
|
||||||
The diff set to remove the typos from.
|
The diff set to remove the typos from.
|
||||||
"""
|
"""
|
||||||
#remove typo at beginning of string
|
#remove typo at beginning of string
|
||||||
if len(diff) >= 2:
|
if len(diff) >= 2:
|
||||||
if diff[0][0] != "equal" and self.__opLength(diff[0]) <= self.maxTypoSize and \
|
if diff[0][0] != "equal" and self.__op_length(diff[0]) <= self.max_typo_size and \
|
||||||
self.__opLength(diff[1]) >= self.minFragmentSize:
|
self.__op_length(diff[1]) >= self.min_fragment_size:
|
||||||
del diff[0]
|
del diff[0]
|
||||||
#remove typos in the middle of string
|
#remove typos in the middle of string
|
||||||
if len(diff) >= 3:
|
if len(diff) >= 3:
|
||||||
for index in range(len(diff) - 3, -1, -1):
|
for index in range(len(diff) - 3, -1, -1):
|
||||||
if self.__opLength(diff[index]) >= self.minFragmentSize and \
|
if self.__op_length(diff[index]) >= self.min_fragment_size and \
|
||||||
diff[index + 1][0] != "equal" and self.__opLength(diff[index + 1]) <= self.maxTypoSize and \
|
diff[index + 1][0] != "equal" and self.__op_length(diff[index + 1]) <= self.max_typo_size and \
|
||||||
self.__opLength(diff[index + 2]) >= self.minFragmentSize:
|
self.__op_length(diff[index + 2]) >= self.min_fragment_size:
|
||||||
del diff[index + 1]
|
del diff[index + 1]
|
||||||
#remove typo at the end of string
|
#remove typo at the end of string
|
||||||
if len(diff) >= 2:
|
if len(diff) >= 2:
|
||||||
if self.__opLength(diff[-2]) >= self.minFragmentSize and \
|
if self.__op_length(diff[-2]) >= self.min_fragment_size and \
|
||||||
diff[-1][0] != "equal" and self.__opLength(diff[-1]) <= self.maxTypoSize:
|
diff[-1][0] != "equal" and self.__op_length(diff[-1]) <= self.max_typo_size:
|
||||||
del diff[-1]
|
del diff[-1]
|
||||||
|
|
||||||
#merge fragments
|
#merge fragments
|
||||||
for index in range(len(diff) - 2, -1, -1):
|
for index in range(len(diff) - 2, -1, -1):
|
||||||
if diff[index][0] == "equal" and self.__opLength(diff[index]) >= self.minFragmentSize and \
|
if diff[index][0] == "equal" and self.__op_length(diff[index]) >= self.min_fragment_size and \
|
||||||
diff[index + 1][0] == "equal" and self.__opLength(diff[index + 1]) >= self.minFragmentSize:
|
diff[index + 1][0] == "equal" and self.__op_length(diff[index + 1]) >= self.min_fragment_size:
|
||||||
diff[index] = ("equal", diff[index][1], diff[index + 1][2], diff[index][3],
|
diff[index] = ("equal", diff[index][1], diff[index + 1][2], diff[index][3],
|
||||||
diff[index + 1][4])
|
diff[index + 1][4])
|
||||||
del diff[index + 1]
|
del diff[index + 1]
|
||||||
|
|
||||||
return diff
|
return diff
|
||||||
|
|
||||||
def __lengthOfEqualBlocks(self, diff):
|
def __length_of_equal_blocks(self, diff):
|
||||||
"""
|
"""
|
||||||
Return the total length of all equal blocks in a diff set.
|
Return the total length of all equal blocks in a diff set.
|
||||||
Blocks smaller than minBlockSize are not counted.
|
Blocks smaller than min_block_size are not counted.
|
||||||
|
|
||||||
``diff``
|
``diff``
|
||||||
The diff set to return the length for.
|
The diff set to return the length for.
|
||||||
"""
|
"""
|
||||||
length = 0
|
length = 0
|
||||||
for element in diff:
|
for element in diff:
|
||||||
if element[0] == "equal" and self.__opLength(element) >= self.minBlockSize:
|
if element[0] == "equal" and self.__op_length(element) >= self.min_block_size:
|
||||||
length += self.__opLength(element)
|
length += self.__op_length(element)
|
||||||
return length
|
return length
|
||||||
|
|
||||||
def __lengthOfLongestEqualBlock(self, diff):
|
def __length_of_longest_equal_block(self, diff):
|
||||||
"""
|
"""
|
||||||
Return the length of the largest equal block in a diff set.
|
Return the length of the largest equal block in a diff set.
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class DuplicateSongFinder(object):
|
|||||||
"""
|
"""
|
||||||
length = 0
|
length = 0
|
||||||
for element in diff:
|
for element in diff:
|
||||||
if element[0] == "equal" and self.__opLength(element) > length:
|
if element[0] == "equal" and self.__op_length(element) > length:
|
||||||
length = self.__opLength(element)
|
length = self.__op_length(element)
|
||||||
return length
|
return length
|
||||||
|
|
||||||
|
@ -37,27 +37,22 @@ class TestLib(TestCase):
|
|||||||
|
|
||||||
def songs_probably_equal_test(self):
|
def songs_probably_equal_test(self):
|
||||||
"""
|
"""
|
||||||
Test the DuplicateSongFinder.songsProbablyEqual function.
|
Test the DuplicateSongFinder.songs_probably_equal function.
|
||||||
"""
|
"""
|
||||||
full_lyrics =u'''amazing grace how sweet the sound that saved a wretch like me i once was lost but now am found was
|
full_lyrics =u'''amazing grace how sweet the sound that saved a wretch like me i once was lost but now am
|
||||||
blind but now i see twas grace that taught my heart to fear and grace my fears relieved how precious did that grace
|
found was blind but now i see twas grace that taught my heart to fear and grace my fears relieved how
|
||||||
appear the hour i first believed through many dangers toils and snares i have already come tis grace that brought
|
precious did that grace appear the hour i first believed through many dangers toils and snares i have already
|
||||||
me safe thus far and grace will lead me home the lord has promised good to me his word my hope secures he will my
|
come tis grace that brought me safe thus far and grace will lead me home'''
|
||||||
shield and portion be as long as life endures yea when this flesh and heart shall fail and mortal life shall cease
|
short_lyrics =u'''twas grace that taught my heart to fear and grace my fears relieved how precious did that
|
||||||
i shall possess within the veil a life of joy and peace when weve been here ten thousand years bright shining as
|
grace appear the hour i first believed'''
|
||||||
the sun weve no less days to sing gods praise than when weve first begun'''
|
error_lyrics =u'''amazing how sweet the trumpet that saved a wrench like me i once was losst but now am
|
||||||
short_lyrics =u'''twas grace that taught my heart to fear and grace my fears relieved how precious did that grace
|
found waf blind but now i see it was grace that taught my heart to fear and grace my fears relieved how
|
||||||
appear the hour i first believed'''
|
precious did that grace appppppppear the hour i first believedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx snares i have
|
||||||
error_lyrics =u'''amazing grace how sweet the sound that saved a wretch like me i once was lost but now am found was
|
already come to this grace that brought me safe so far and grace will lead me home'''
|
||||||
blind but now i see twas grace that taught my heart to fear and grace my fears relieved how precious did that grace
|
different_lyrics=u'''on a hill far away stood an old rugged cross the emblem of suffering and shame and i love
|
||||||
appear the hour i first believedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx snares i have already come tis grace that brought
|
that old cross where the dearest and best for a world of lost sinners was slain so ill cherish the old rugged
|
||||||
me safe thus far and grace will lead me home the lord has promised good to me his word my hope secures he will my
|
cross till my trophies at last i lay down i will cling to the old rugged cross and exchange it some day for a
|
||||||
shield andwhen this flcsh and heart shall fail and mortal life shall cease
|
crown'''
|
||||||
i shall possess within the veila lifeofjoy and peace when weve been here ten thousand years bright shining as
|
|
||||||
the sun weve no less days to sing gods praise than when weve first begun'''
|
|
||||||
different_lyrics=u'''on a hill far away stood an old rugged cross the emblem of suffering and shame and i love that
|
|
||||||
old cross where the dearest and best for a world of lost sinners was slain so ill cherish the old rugged cross till
|
|
||||||
my trophies at last i lay down i will cling to the old rugged cross and exchange it some day for a crown'''
|
|
||||||
dsf = DuplicateSongFinder()
|
dsf = DuplicateSongFinder()
|
||||||
song1 = MagicMock()
|
song1 = MagicMock()
|
||||||
song2 = MagicMock()
|
song2 = MagicMock()
|
||||||
@ -67,7 +62,7 @@ class TestLib(TestCase):
|
|||||||
song2.search_lyrics = full_lyrics
|
song2.search_lyrics = full_lyrics
|
||||||
|
|
||||||
#WHEN: We compare those songs for equality
|
#WHEN: We compare those songs for equality
|
||||||
result = dsf.songsProbablyEqual(song1, song2)
|
result = dsf.songs_probably_equal(song1, song2)
|
||||||
|
|
||||||
#THEN: The result should be True
|
#THEN: The result should be True
|
||||||
assert result is True, u'The result should be True'
|
assert result is True, u'The result should be True'
|
||||||
@ -77,7 +72,7 @@ class TestLib(TestCase):
|
|||||||
song2.search_lyrics = short_lyrics
|
song2.search_lyrics = short_lyrics
|
||||||
|
|
||||||
#WHEN: We compare those songs for equality
|
#WHEN: We compare those songs for equality
|
||||||
result = dsf.songsProbablyEqual(song1, song2)
|
result = dsf.songs_probably_equal(song1, song2)
|
||||||
|
|
||||||
#THEN: The result should be True
|
#THEN: The result should be True
|
||||||
assert result is True, u'The result should be True'
|
assert result is True, u'The result should be True'
|
||||||
@ -87,7 +82,7 @@ class TestLib(TestCase):
|
|||||||
song2.search_lyrics = error_lyrics
|
song2.search_lyrics = error_lyrics
|
||||||
|
|
||||||
#WHEN: We compare those songs for equality
|
#WHEN: We compare those songs for equality
|
||||||
result = dsf.songsProbablyEqual(song1, song2)
|
result = dsf.songs_probably_equal(song1, song2)
|
||||||
|
|
||||||
#THEN: The result should be True
|
#THEN: The result should be True
|
||||||
assert result is True, u'The result should be True'
|
assert result is True, u'The result should be True'
|
||||||
@ -97,7 +92,7 @@ class TestLib(TestCase):
|
|||||||
song2.search_lyrics = different_lyrics
|
song2.search_lyrics = different_lyrics
|
||||||
|
|
||||||
#WHEN: We compare those songs for equality
|
#WHEN: We compare those songs for equality
|
||||||
result = dsf.songsProbablyEqual(song1, song2)
|
result = dsf.songs_probably_equal(song1, song2)
|
||||||
|
|
||||||
#THEN: The result should be False
|
#THEN: The result should be False
|
||||||
assert result is False, u'The result should be False'
|
assert result is False, u'The result should be False'
|
||||||
|
Loading…
Reference in New Issue
Block a user