Skip to content

Commit 0c17901

Browse files
committed
PICARD-187: Support for manually removing cover art
PICARD-187: Support for manually removing cover art finishing PICARD-187
1 parent 647fc3b commit 0c17901

File tree

7 files changed

+68
-1
lines changed

7 files changed

+68
-1
lines changed

picard/formats/apev2.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ def _remove_deleted_tags(self, metadata, tags):
263263
if real_name in tags:
264264
del tags[real_name]
265265

266+
if self.metadata.images._deleted:
267+
for tag in tags:
268+
if tag.lower().startswith('cover art'):
269+
del tags[tag]
270+
266271
def _get_tag_name(self, name):
267272
if name in self.__casemap:
268273
return self.__casemap[name]

picard/formats/asf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ def _remove_deleted_tags(self, metadata, tags):
304304
real_name = self._get_tag_name(tag)
305305
if real_name and real_name in tags:
306306
del tags[real_name]
307+
if self.metadata.images._deleted:
308+
del tags['WM/Picture']
307309

308310
@classmethod
309311
def supports_tag(cls, name):

picard/formats/id3.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,11 @@ def _remove_deleted_tags(self, metadata, tags):
659659
except KeyError:
660660
pass
661661

662+
if self.metadata.images._deleted:
663+
for key, frame in list(tags.items()):
664+
if frame.FrameID == 'APIC':
665+
del tags[key]
666+
662667
@classmethod
663668
def supports_tag(cls, name):
664669
return ((name and not name.startswith('~') and name not in UNSUPPORTED_TAGS)

picard/formats/mp4.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ def _remove_deleted_tags(self, metadata, tags):
340340
if tag not in {'totaltracks', 'totaldiscs'}:
341341
del tags[real_name]
342342

343+
if self.metadata.images._deleted:
344+
del tags['covr']
345+
343346
@classmethod
344347
def supports_tag(cls, name):
345348
return (name

picard/formats/vorbis.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def _save(self, filename, metadata):
321321
base64.b64encode(picture.write()).decode('ascii'))
322322

323323
file.tags.update(tags)
324-
324+
self._clear_cover_art(file)
325325
self._remove_deleted_tags(metadata, file.tags)
326326

327327
kwargs = {}
@@ -357,6 +357,17 @@ def _remove_deleted_tags(self, metadata, tags):
357357
# both tag and real_name are to be deleted in this case
358358
del tags[tag]
359359
del tags[real_name]
360+
361+
def _clear_cover_art(self, file):
362+
is_flac = self._File == mutagen.flac.FLAC
363+
364+
if self.metadata.images._deleted:
365+
if is_flac:
366+
file.clear_pictures()
367+
else:
368+
for tag in file:
369+
if tag.lower().startswith('metadata_block_picture'):
370+
del file.tags[tag]
360371

361372
def _get_tag_name(self, name):
362373
if name == '~rating':

picard/ui/coverartbox.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ def open_release_page(self):
347347
lookup = self.tagger.get_file_lookup()
348348
lookup.album_lookup(self.release)
349349

350+
def image_delete(obj, image_index):
351+
obj.metadata.images.strip_selected_image(image_index)
352+
obj.metadata_images_changed.emit()
350353

351354
def set_image_replace(obj, coverartimage):
352355
obj.metadata.images.strip_front_images()
@@ -545,6 +548,28 @@ def load_remote_image(self, url, data):
545548
log.warning("Can't load image: %s", e)
546549
return
547550

551+
def delete_cover_art(self):
552+
if not self.item or not self.item.can_show_coverart:
553+
return
554+
555+
metadata = self.item.metadata
556+
if not metadata or not metadata.images:
557+
return
558+
559+
cover_art_list = [image.source or _("Unnamed Cover Art") for image in metadata.images]
560+
561+
selected_item, ok_pressed = QtWidgets.QInputDialog.getItem(self, _("Delete Cover Art"),
562+
_("Select the cover art image to delete:"), cover_art_list, 0, False)
563+
564+
if ok_pressed:
565+
selected_index = cover_art_list.index(selected_item)
566+
if selected_index < len(metadata.images):
567+
image_delete(self.item, selected_index)
568+
self.update_display(force=True)
569+
else:
570+
QtWidgets.QMessageBox.warning(self, _("Invalid Selection"),
571+
_("Please select a valid cover art image."))
572+
548573
def _try_load_remote_image(self, url, data):
549574
coverartimage = CoverArtImage(
550575
url=url.toString(),
@@ -634,6 +659,12 @@ def contextMenuEvent(self, event):
634659
show_more_details_action.triggered.connect(self.show_cover_art_info)
635660
menu.addAction(show_more_details_action)
636661

662+
if self.item and self.item.can_show_coverart:
663+
name = _("Delete cover art")
664+
delete_cover_art_action = QtGui.QAction(name, self.parent)
665+
delete_cover_art_action.triggered.connect(self.delete_cover_art)
666+
menu.addAction(delete_cover_art_action)
667+
637668
if self.orig_cover_art.isVisible():
638669
name = _("Keep original cover art")
639670
use_orig_value_action = QtGui.QAction(name, self.parent)

picard/util/imagelist.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(self, iterable=()):
3333
self._images = list(iterable)
3434
self._hash_dict = {}
3535
self._changed = True
36+
self._deleted = False
3637

3738
def __len__(self):
3839
return len(self._images)
@@ -50,6 +51,7 @@ def __delitem__(self, index):
5051

5152
def insert(self, index, value):
5253
self._changed = True
54+
self._deleted = False
5355
return self._images.insert(index, value)
5456

5557
def __repr__(self):
@@ -95,6 +97,14 @@ def strip_front_images(self):
9597
self._images = [image for image in self._images if not image.is_front_image()]
9698
self._changed = True
9799

100+
def strip_selected_image(self, image_index):
101+
if len(self._images) > image_index:
102+
del self._images[image_index]
103+
if len(self._images) == 0:
104+
self._deleted = True
105+
else:
106+
raise IndexError("Invalid image index")
107+
98108
def hash_dict(self):
99109
if self._changed:
100110
self._hash_dict = {img.datahash.hash(): img for img in self._images}

0 commit comments

Comments
 (0)