diff --git a/picard/coverart.py b/picard/coverart.py index 142e379d3..fef104838 100644 --- a/picard/coverart.py +++ b/picard/coverart.py @@ -101,8 +101,15 @@ def _coverart_downloaded(album, metadata, release, try_list, coverinfos, data, h filename = None if not is_front_image(coverinfos) and config.setting["caa_image_type_as_filename"]: filename = coverinfos['type'] + try: - image = Image(data, mime, coverinfos['type'], coverinfos['desc']) + metadata.make_and_add_image(mime, data, + imagetype=coverinfos['type'], + comment=coverinfos['desc']) + for track in album._new_tracks: + track.metadata.make_and_add_image(mime, data, + imagetype=coverinfos['type'], + comment=coverinfos['desc']) except (IOError, OSError), e: album.error_append(e.message) album._finalize_loading(error=True) @@ -110,10 +117,6 @@ def _coverart_downloaded(album, metadata, release, try_list, coverinfos, data, h # save them in the temporary folder, abort. return - metadata.add_image(image) - for track in album._new_tracks: - track.metadata.add_image(image) - # If the image already was a front image, there might still be some # other front images in the try_list - remove them. if is_front_image(coverinfos): diff --git a/picard/metadata.py b/picard/metadata.py index 2ac7103f8..2cee4b9c3 100644 --- a/picard/metadata.py +++ b/picard/metadata.py @@ -21,9 +21,11 @@ import os.path import shutil import sys import tempfile +import traceback -from os import fdopen, close, unlink +from hashlib import md5 +from os import fdopen, unlink from PyQt4.QtCore import QObject from picard import config, log from picard.plugin import ExtensionPoint @@ -171,15 +173,11 @@ class Metadata(dict): self.images = [] self.length = 0 - def add_image(self, image): - """Adds the Image object ``image`` to this Metadata object. - """ - self.images.append(image) - def make_and_add_image(self, mime, data, filename=None, comment="", - imagetype="front"): + imagetype="front"): """Build a new image object from ``data`` and adds it to this Metadata - object. + object. If an image with the same MD5 hash has already been added to + any Metadata object, that file will be reused. Arguments: mime -- The mimetype of the image @@ -188,7 +186,13 @@ class Metadata(dict): comment -- image description or comment, default to '' imagetype -- main type as a string, default to 'front' """ - image = Image(data, mime, imagetype, comment) + m = md5() + m.update(data) + datahash = m.hexdigest() + image = QObject.tagger.images[datahash] + if image is None: + image = Image(data, mime, imagetype, comment) + QObject.tagger.images[datahash] = image self.images.append(image) def remove_image(self, index): diff --git a/picard/tagger.py b/picard/tagger.py index 1180ce853..5e23ed95f 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -31,6 +31,7 @@ import re import shutil import signal import sys +from collections import defaultdict from functools import partial from itertools import chain @@ -165,6 +166,7 @@ class Tagger(QtGui.QApplication): self.albums = {} self.release_groups = {} self.mbid_redirects = {} + self.images = defaultdict(lambda: None) self.unmatched_files = UnmatchedFiles() self.nats = None self.window = MainWindow() diff --git a/picard/ui/infodialog.py b/picard/ui/infodialog.py index 71d5c14d1..6e151afe9 100644 --- a/picard/ui/infodialog.py +++ b/picard/ui/infodialog.py @@ -18,7 +18,9 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os.path +import traceback from PyQt4 import QtGui, QtCore +from picard import log from picard.util import format_time, encode_filename, bytes2human from picard.ui.ui_infodialog import Ui_InfoDialog @@ -47,7 +49,11 @@ class InfoDialog(QtGui.QDialog): return for image in images: - data = image.data + try: + data = image.data + except (OSError, IOError), e: + log.error(traceback.format_exc()) + continue size = len(data) item = QtGui.QListWidgetItem() pixmap = QtGui.QPixmap()