Fix various cover drop issues

This patch adds https support, so users can drag covers from amazon.

Also fixes the imgurl query handling so users can drag covers from
google images thumbnails (but large resolution images will be downloaded).

It also adds support for dropped octet-stream data, so chromium users
can drag "opened" images from google images even if the link actually
points to the url containing the image, since chromium adds the
image data to the drop event. Unfortunately, firefox doesn't do that,
so firefox users will have to drag thumbnails (but the same large
resolution image will be used in any case)
This commit is contained in:
Antonio Larrosa
2017-02-09 08:15:37 +01:00
parent 0b6207a40d
commit f2e2188ba4

View File

@@ -33,7 +33,7 @@ class ActiveLabel(QtGui.QLabel):
"""Clickable QLabel."""
clicked = QtCore.pyqtSignal()
imageDropped = QtCore.pyqtSignal(QtCore.QUrl)
imageDropped = QtCore.pyqtSignal(QtCore.QUrl, QtCore.QByteArray)
def __init__(self, active=True, *args):
QtGui.QLabel.__init__(self, *args)
@@ -54,16 +54,20 @@ class ActiveLabel(QtGui.QLabel):
def dragEnterEvent(self, event):
for url in event.mimeData().urls():
if url.scheme() in ('http', 'file'):
if url.scheme() in ('https', 'http', 'file'):
event.acceptProposedAction()
break
def dropEvent(self, event):
accepted = False
# Chromium includes the actual data of the dragged image in the drop event. This
# is useful for Google Images, where the url links to the page that contains the image
# so we use it if the downloaded url is not an image.
droppedData = event.mimeData().data('application/octet-stream')
for url in event.mimeData().urls():
if url.scheme() in ('http', 'file'):
if url.scheme() in ('https', 'http', 'file'):
accepted = True
self.imageDropped.emit(url)
self.imageDropped.emit(url, droppedData)
if accepted:
event.acceptProposedAction()
@@ -150,15 +154,19 @@ class CoverArtBox(QtGui.QGroupBox):
lookup = self.tagger.get_file_lookup()
lookup.albumLookup(self.release)
def fetch_remote_image(self, url):
def fetch_remote_image(self, url, fallbackData=None):
if self.item is None:
return
if url.scheme() == 'http':
if url.scheme() in ('https', 'http'):
path = url.encodedPath()
if url.hasQuery():
path += '?' + url.encodedQuery()
self.tagger.xmlws.get(url.encodedHost(), url.port(80), path,
partial(self.on_remote_image_fetched, url),
if url.scheme() == 'https':
port = 443
else:
port = 80
self.tagger.xmlws.get(str(url.encodedHost()), url.port(port), str(path),
partial(self.on_remote_image_fetched, url, fallbackData=fallbackData),
xml=False,
priority=True, important=True)
elif url.scheme() == 'file':
@@ -169,16 +177,29 @@ class CoverArtBox(QtGui.QGroupBox):
data = f.read()
self.load_remote_image(url, mime, data)
def on_remote_image_fetched(self, url, data, reply, error):
def on_remote_image_fetched(self, url, data, reply, error, fallbackData=None):
mime = reply.header(QtNetwork.QNetworkRequest.ContentTypeHeader)
if mime in ('image/jpeg', 'image/png'):
self.load_remote_image(url, mime, data)
elif reply.url().hasQueryItem("imgurl"):
elif url.hasQueryItem("imgurl"):
# This may be a google images result, try to get the URL which is encoded in the query
url = QtCore.QUrl(reply.url().queryItemValue("imgurl"))
url = QtCore.QUrl(url.queryItemValue("imgurl"))
self.fetch_remote_image(url)
else:
log.warning("Can't load image with MIME-Type %s", mime)
log.warning("Can't load remote image with MIME-Type %s", mime)
if fallbackData:
# Tests for image format obtained from file-magic
if fallbackData[:2]=='\xff\xd8':
mime = 'image/jpeg'
elif fallbackData[:8]=='\x89PNG\x0d\x0a\x1a\x0a':
mime = 'image/png'
else:
mime = None
if mime:
log.warning("Trying the dropped %s data", mime)
self.load_remote_image(url, mime, fallbackData)
def load_remote_image(self, url, mime, data):
try: