Ejemplo n.º 1
0
def run_extractor(tagger,
                  input_path,
                  extractor_callback,
                  response,
                  reply,
                  error,
                  main_thread=False):
    duplicate = False
    # Check if AcousticBrainz server answered with the json file for the recording id
    if not error:
        # If it did, mark file as duplicate and skip extraction
        try:
            load_json(response)
            duplicate = True
        except json.JSONDecodeError:
            pass

    if duplicate:
        # If an entry for the same recording ID already exists
        # using the same extractor version exists, skip extraction
        results = (None, 0, "Duplicate")
        extractor_callback(results, None)
    else:
        if main_thread:
            # Run extractor on main thread, used for testing
            extractor_callback(extractor(tagger, input_path), None)
        else:
            # Run extractor on a different thread and call the callback when done
            run_task(partial(extractor, tagger, input_path),
                     extractor_callback)
Ejemplo n.º 2
0
 def on_refresh_access_token_finished(self, callback, data, http, error):
     access_token = None
     try:
         if error:
             log.error("OAuth: access_token refresh failed: %s", data)
             if http.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 400:
                 response = load_json(data)
                 if response["error"] == "invalid_grant":
                     self.forget_refresh_token()
         else:
             response = load_json(data)
             self.set_access_token(response["access_token"], response["expires_in"])
             access_token = response["access_token"]
     finally:
         callback(access_token)
Ejemplo n.º 3
0
 def on_refresh_access_token_finished(self, callback, data, http, error):
     access_token = None
     try:
         if error:
             log.error("OAuth: access_token refresh failed: %s", data)
             if http.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 400:
                 response = load_json(data)
                 if response["error"] == "invalid_grant":
                     self.forget_refresh_token()
         else:
             response = load_json(data)
             self.set_access_token(response["access_token"], response["expires_in"])
             access_token = response["access_token"]
     finally:
         callback(access_token)
Ejemplo n.º 4
0
 def _batch_submit_finished(self, submissions, next_func, document, http,
                            error):
     if error:
         try:
             error = load_json(document)
             message = error["error"]["message"]
         except BaseException:
             message = ""
         mparms = {'error': http.errorString(), 'message': message}
         log.error(
             "AcoustID: submission failed with error '%(error)s': %(message)s"
             % mparms)
         self.tagger.window.set_statusbar_message(N_(
             "AcoustID submission failed with error '%(error)s': %(message)s"
         ),
                                                  mparms,
                                                  echo=None,
                                                  timeout=3000)
     else:
         log.debug('AcoustID: %d fingerprints successfully submitted',
                   len(submissions))
         for file, submission in submissions:
             submission.orig_recordingid = submission.recordingid
             file.update()
         self._check_unsubmitted()
     next_func()
Ejemplo n.º 5
0
def result(album, metadata, data, reply, error):
    if error:
        album._requests -= 1
        album._finalize_loading(None)
        return

    moods = []
    genres = []
    try:
        data = load_json(data).get(metadata["musicbrainz_recordingid"])
        if data and "0" in data and "highlevel" in data["0"]:
            data = data["0"]["highlevel"]
            for k, v in data.items():
                if k.startswith("genre_") and not v["value"].startswith("not_"):
                    genres.append(v["value"])
                if k.startswith("mood_") and not v["value"].startswith("not_"):
                    moods.append(v["value"])

            metadata["genre"] = genres
            metadata["mood"] = moods
            log.debug("%s: Track %s (%s) Parsed response (genres: %s, moods: %s)", PLUGIN_NAME, metadata["musicbrainz_recordingid"], metadata["title"], str(genres), str(moods))
    except Exception as e:
        log.error("%s: Track %s (%s) Error parsing response: %s", PLUGIN_NAME, metadata["musicbrainz_recordingid"], metadata["title"], str(e))
    finally:
        album._requests -= 1
        album._finalize_loading(None)
Ejemplo n.º 6
0
 def __fingerprint_submission_finished(self, fingerprints, document, http, error):
     if error:
         try:
             error = load_json(document)
             message = error["error"]["message"]
         except :
             message = ""
         mparms = {
             'error': http.errorString(),
             'message': message
         }
         log.error(
             "AcoustID: submission failed with error '%(error)s': %(message)s" %
             mparms)
         self.tagger.window.set_statusbar_message(
             N_("AcoustID submission failed with error '%(error)s': %(message)s"),
             mparms,
             echo=None,
             timeout=3000
         )
     else:
         log.debug('AcoustID: successfully submitted')
         self.tagger.window.set_statusbar_message(
             N_('AcoustIDs successfully submitted.'),
             echo=None,
             timeout=3000
         )
         for submission in fingerprints:
             submission.orig_recordingid = submission.recordingid
         self._check_unsubmitted()
Ejemplo n.º 7
0
 def _extract_error_description(self, http, data):
     try:
         response = load_json(data)
         return response['error_description']
     except (JSONDecodeError, KeyError, TypeError):
         return _('Unexpected request error (HTTP code %s)'
                  ) % self.webservice.http_response_code(http)
Ejemplo n.º 8
0
 def _releases_json_loaded(self, response, reply, error, callback=None):
     '''Processes response from specified website api query.'''
     if error:
         log.error(
             _("Error loading Picard releases list: {error_message}").
             format(error_message=reply.errorString(), ))
         if self._show_always:
             QMessageBox.information(
                 self._parent, _("Picard Update"),
                 _("Unable to retrieve the latest version information from the website.\n(https://{url}{endpoint})"
                   ).format(
                       url=PLUGINS_API['host'],
                       endpoint=PLUGINS_API['endpoint']['releases'],
                   ), QMessageBox.Ok, QMessageBox.Ok)
     else:
         self._available_versions = load_json(response)['versions']
         for key in self._available_versions:
             log.debug(
                 "Version key '{version_key}' --> {version_information}".
                 format(
                     version_key=key,
                     version_information=self._available_versions[key],
                 ))
         self._display_results()
     if callback:
         callback(not error)
Ejemplo n.º 9
0
    def _json_downloaded(self, release_group_id, data, reply, error):
        self.album._requests -= 1

        if error:
            if error != QNetworkReply.ContentNotFoundError:
                error_level = log.error
            else:
                error_level = log.debug
            error_level("Problem requesting metadata in fanart.tv plugin: %s",
                        error)
        else:
            try:
                response = load_json(data)
                release = response["albums"][release_group_id]

                if "albumcover" in release:
                    covers = release["albumcover"]
                    types = ["front"]
                    self._select_and_add_cover_art(covers, types)

                if "cdart" in release and \
                    (config.setting["fanarttv_use_cdart"] == OPTION_CDART_ALWAYS
                        or (config.setting["fanarttv_use_cdart"] == OPTION_CDART_NOALBUMART
                            and "albumcover" not in release)):
                    covers = release["cdart"]
                    types = ["medium"]
                    if not "albumcover" in release:
                        types.append("front")
                    self._select_and_add_cover_art(covers, types)
            except:
                log.error(
                    "Problem processing downloaded metadata in fanart.tv plugin: %s",
                    traceback.format_exc())

        self.next_in_queue()
Ejemplo n.º 10
0
 def __fingerprint_submission_finished(self, fingerprints, document, http, error):
     if error:
         try:
             error = load_json(document)
             message = error["error"]["message"]
         except :
             message = ""
         mparms = {
             'error': http.errorString(),
             'message': message
         }
         log.error(
             "AcoustID: submission failed with error '%(error)s': %(message)s" %
             mparms)
         self.tagger.window.set_statusbar_message(
             N_("AcoustID submission failed with error '%(error)s': %(message)s"),
             mparms,
             echo=None,
             timeout=3000
         )
     else:
         log.debug('AcoustID: successfully submitted')
         self.tagger.window.set_statusbar_message(
             N_('AcoustIDs successfully submitted.'),
             echo=None,
             timeout=3000
         )
         for submission in fingerprints:
             submission.orig_recordingid = submission.recordingid
         self._check_unsubmitted()
Ejemplo n.º 11
0
 def process_data(self, album, track_metadata, response, reply, error):
     if error:
         log.error(
             "%s: Network error retrieving acousticBrainz data for recordingId %s",
             PLUGIN_NAME, track_metadata['musicbrainz_recordingid'])
         self.album_remove_request(album)
         return
     try:
         data = load_json(response)
     except JSONDecodeError:
         log.error(
             "%s: Network error retrieving AcousticBrainz data for recordingId %s",
             PLUGIN_NAME, track_metadata['musicbrainz_recordingid'])
         self.album_remove_request(album)
         return
     if "tonal" in data:
         if "key_key" in data["tonal"]:
             key = data["tonal"]["key_key"]
             if "key_scale" in data["tonal"]:
                 scale = data["tonal"]["key_scale"]
                 if scale == "minor":
                     key += "m"
             track_metadata["key"] = key
             log.debug("%s: Track '%s' is in key %s", PLUGIN_NAME,
                       track_metadata["title"], key)
     if "rhythm" in data:
         if "bpm" in data["rhythm"]:
             bpm = int(data["rhythm"]["bpm"] + 0.5)
             track_metadata["bpm"] = bpm
             log.debug("%s: Track '%s' has %s bpm", PLUGIN_NAME,
                       track_metadata["title"], bpm)
     self.album_remove_request(album)
Ejemplo n.º 12
0
 def on_fetch_username_finished(self, callback, data, http, error):
     successful = False
     try:
         if error:
             log.error("OAuth: username fetching failed: %s", data)
         else:
             response = load_json(data)
             self.set_username(response["sub"])
             successful = True
     finally:
         callback(successful)
Ejemplo n.º 13
0
 def on_fetch_username_finished(self, callback, data, http, error):
     successful = False
     try:
         if error:
             log.error("OAuth: username fetching failed: %s", data)
         else:
             response = load_json(data)
             self.set_username(response["sub"])
             successful = True
     finally:
         callback(successful)
Ejemplo n.º 14
0
 def _plugins_json_loaded(self, response, reply, error, callback=None):
     if error:
         self.tagger.window.set_statusbar_message(
             N_("Error loading plugins list: %(error)s"),
             {'error': reply.errorString()},
             echo=log.error
         )
     else:
         self._available_plugins = [PluginData(data, key) for key, data in
                                    load_json(response)['plugins'].items()]
     if callback:
         callback()
Ejemplo n.º 15
0
 def on_exchange_authorization_code_finished(self, scopes, callback, data, http, error):
     successful = False
     try:
         if error:
             log.error("OAuth: authorization_code exchange failed: %s", data)
         else:
             response = load_json(data)
             self.set_refresh_token(response["refresh_token"], scopes)
             self.set_access_token(response["access_token"], response["expires_in"])
             successful = True
     finally:
         callback(successful)
Ejemplo n.º 16
0
 def on_exchange_authorization_code_finished(self, scopes, callback, data, http, error):
     successful = False
     try:
         if error:
             log.error("OAuth: authorization_code exchange failed: %s", data)
         else:
             response = load_json(data)
             self.set_refresh_token(response["refresh_token"], scopes)
             self.set_access_token(response["access_token"], response["expires_in"])
             successful = True
     finally:
         callback(successful)
Ejemplo n.º 17
0
 def _plugins_json_loaded(self, response, reply, error, callback=None):
     if error:
         self.tagger.window.set_statusbar_message(
             N_("Error loading plugins list: %(error)s"),
             {'error': reply.errorString()},
             echo=log.error
         )
     else:
         self._available_plugins = [PluginData(data, key) for key, data in
                                    load_json(response)['plugins'].items()]
     if callback:
         callback()
Ejemplo n.º 18
0
 def on_refresh_access_token_finished(self, callback, data, http, error):
     access_token = None
     try:
         if error:
             log.error("OAuth: access_token refresh failed: %s", data)
             if self._http_code(http) == 400:
                 response = load_json(data)
                 if response["error"] == "invalid_grant":
                     self.forget_refresh_token()
         else:
             access_token = data["access_token"]
             self.set_access_token(access_token, data["expires_in"])
     except Exception as e:
         log.error('OAuth: Unexpected error handling access token response: %r', e)
     finally:
         callback(access_token=access_token)
Ejemplo n.º 19
0
 def on_refresh_access_token_finished(self, callback, data, http, error):
     access_token = None
     try:
         if error:
             log.error("OAuth: access_token refresh failed: %s", data)
             if http.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 400:
                 response = load_json(data)
                 if response["error"] == "invalid_grant":
                     self.forget_refresh_token()
         else:
             self.set_access_token(data["access_token"], data["expires_in"])
             access_token = data["access_token"]
     except Exception as e:
         log.error('OAuth: Unexpected error handling access token response: %r', e)
     finally:
         callback(access_token)
Ejemplo n.º 20
0
    def _batch_submit_finished(self, submissions, batch, previous_errors,
                               document, http, error):
        if error:
            # re-add batched items to remaining list
            submissions.extend(batch)

            response_code = self._acoustid_api.webservice.http_response_code(
                http)
            if response_code == 413:
                self.max_batch_size = int(self.max_batch_size *
                                          self.BATCH_SIZE_REDUCTION_FACTOR)
                log.warn(
                    "AcoustID: payload too large, batch size reduced to %d",
                    self.max_batch_size)
            else:
                try:
                    errordoc = load_json(document)
                    message = errordoc["error"]["message"]
                except BaseException:
                    message = ""
                mparms = {'error': http.errorString(), 'message': message}
                previous_errors.append(mparms)
                log_msg = N_(
                    "AcoustID submission failed with error '%(error)s': %(message)s"
                )
                log.error(log_msg, mparms)
                self.tagger.window.set_statusbar_message(log_msg,
                                                         mparms,
                                                         echo=None,
                                                         timeout=3000)
        else:
            log.debug('AcoustID: %d fingerprints successfully submitted',
                      len(batch))
            for file, submission in batch:
                submission.orig_recordingid = submission.recordingid
                file.update()
            self._check_unsubmitted()
        self._batch_submit(submissions, previous_errors)
Ejemplo n.º 21
0
    def _caa_json_downloaded(self, row, data, http, error):
        """Handle json reply from CAA server.
        If server replies without error, try to get small thumbnail of front
        coverart of the release.
        """
        if not self.table:
            return

        cover_cell = self.table.cellWidget(row, len(self.table_headers)-1)

        if error:
            cover_cell.not_found()
            return

        try:
            caa_data = load_json(data)
        except ValueError:
            cover_cell.not_found()
            return

        front = None
        for image in caa_data["images"]:
            if image["front"]:
                front = image
                break

        if front:
            url = front["thumbnails"]["small"]
            coverartimage = CaaThumbnailCoverArtImage(url=url)
            self.tagger.xmlws.download(
                coverartimage.host,
                coverartimage.port,
                coverartimage.path,
                partial(self._cover_downloaded, row),
            )
        else:
            cover_cell.not_found()
Ejemplo n.º 22
0
    def _caa_json_downloaded(self, data, http, error):
        """Parse CAA JSON file and queue CAA cover art images for download"""
        self.album._requests -= 1
        if error:
            if not (error == QNetworkReply.ContentNotFoundError and self.ignore_json_not_found_error):
                self.error('CAA JSON error: %s' % (http.errorString()))
        else:
            try:
                caa_data = load_json(data)
            except ValueError:
                self.error("Invalid JSON: %s" % (http.url().toString()))
            else:
                imagesize = config.setting["caa_image_size"]
                thumbsize = _CAA_THUMBNAIL_SIZE_MAP.get(imagesize, None)
                for image in caa_data["images"]:
                    if config.setting["caa_approved_only"] and not image["approved"]:
                        continue
                    is_pdf = image["image"].endswith('.pdf')
                    if is_pdf and not config.setting["save_images_to_files"]:
                        log.debug("Skipping pdf cover art : %s" %
                                  image["image"])
                        continue
                    # if image has no type set, we still want it to match
                    # pseudo type 'unknown'
                    if not image["types"]:
                        image["types"] = ["unknown"]
                    else:
                        image["types"] = list(map(str.lower, image["types"]))
                    if self.restrict_types:
                        # only keep enabled caa types
                        types = set(image["types"]).intersection(
                            set(self.caa_types))
                    else:
                        types = True
                    if types:
                        if thumbsize is None or is_pdf:
                            url = image["image"]
                        else:
                            url = image["thumbnails"][thumbsize]
                        coverartimage = self.coverartimage_class(
                            url,
                            types=image["types"],
                            is_front=image['front'],
                            comment=image["comment"],
                        )
                        if is_pdf:
                            # thumbnail will be used to "display" PDF in info
                            # dialog
                            thumbnail = self.coverartimage_thumbnail_class(
                                url=image["thumbnails"]['small'],
                                types=image["types"],
                                is_front=image['front'],
                                comment=image["comment"],
                            )
                            self.queue_put(thumbnail)
                            coverartimage.thumbnail = thumbnail
                            # PDFs cannot be saved to tags (as 2014/05/29)
                            coverartimage.can_be_saved_to_tags = False
                        self.queue_put(coverartimage)
                        if config.setting["caa_save_single_front_image"] and \
                                config.setting["save_images_to_files"] and \
                                image["front"]:
                                    break

        self.next_in_queue()
Ejemplo n.º 23
0
    def _caa_json_downloaded(self, data, http, error):
        """Parse CAA JSON file and queue CAA cover art images for download"""
        self.album._requests -= 1
        if error:
            if not (error == QNetworkReply.ContentNotFoundError
                    and self.ignore_json_not_found_error):
                self.error('CAA JSON error: %s' % (http.errorString()))
        else:
            try:
                caa_data = load_json(data)
            except ValueError:
                self.error("Invalid JSON: %s" % (http.url().toString()))
            else:
                if self.restrict_types:
                    log.debug('CAA types: included: %s, excluded: %s' % (
                        self.caa_types,
                        self.caa_types_to_omit,
                    ))
                for image in caa_data["images"]:
                    if config.setting[
                            "caa_approved_only"] and not image["approved"]:
                        continue
                    is_pdf = image["image"].endswith('.pdf')
                    if is_pdf and not config.setting["save_images_to_files"]:
                        log.debug("Skipping pdf cover art : %s" %
                                  image["image"])
                        continue
                    # if image has no type set, we still want it to match
                    # pseudo type 'unknown'
                    if not image["types"]:
                        image["types"] = ["unknown"]
                    else:
                        image["types"] = list(map(str.lower, image["types"]))
                    if self.restrict_types:
                        # only keep enabled caa types
                        types = set(image["types"]).intersection(
                            set(self.caa_types))
                        if types and self.caa_types_to_omit:
                            types = not set(image["types"]).intersection(
                                set(self.caa_types_to_omit))
                        log.debug(
                            'CAA image {status}: {image_name}  {image_types}'.
                            format(
                                status=('accepted' if types else 'rejected'),
                                image_name=image['image'],
                                image_types=image['types'],
                            ))
                    else:
                        types = True
                    if types:
                        urls = caa_url_fallback_list(
                            config.setting["caa_image_size"],
                            image["thumbnails"])
                        if not urls or is_pdf:
                            url = image["image"]
                        else:
                            #FIXME: try other urls in case of 404
                            url = urls[0]
                        coverartimage = self.coverartimage_class(
                            url,
                            types=image["types"],
                            is_front=image['front'],
                            comment=image["comment"],
                        )
                        if urls and is_pdf:
                            # thumbnail will be used to "display" PDF in info
                            # dialog
                            thumbnail = self.coverartimage_thumbnail_class(
                                url=url[0],
                                types=image["types"],
                                is_front=image['front'],
                                comment=image["comment"],
                            )
                            self.queue_put(thumbnail)
                            coverartimage.thumbnail = thumbnail
                            # PDFs cannot be saved to tags (as 2014/05/29)
                            coverartimage.can_be_saved_to_tags = False
                        self.queue_put(coverartimage)
                        if config.setting["caa_save_single_front_image"] and \
                                config.setting["save_images_to_files"] and \
                                image["front"]:
                            break

        self.next_in_queue()
Ejemplo n.º 24
0
    def _caa_json_downloaded(self, data, http, error):
        """Parse CAA JSON file and queue CAA cover art images for download"""
        self.album._requests -= 1
        if error:
            if not (error == QNetworkReply.ContentNotFoundError
                    and self.ignore_json_not_found_error):
                self.error('CAA JSON error: %s' % (http.errorString()))
        else:
            try:
                caa_data = load_json(data)
            except ValueError:
                self.error("Invalid JSON: %s" % (http.url().toString()))
            else:
                imagesize = config.setting["caa_image_size"]
                thumbsize = _CAA_THUMBNAIL_SIZE_MAP.get(imagesize, None)
                for image in caa_data["images"]:
                    if config.setting[
                            "caa_approved_only"] and not image["approved"]:
                        continue
                    is_pdf = image["image"].endswith('.pdf')
                    if is_pdf and not config.setting["save_images_to_files"]:
                        log.debug("Skipping pdf cover art : %s" %
                                  image["image"])
                        continue
                    # if image has no type set, we still want it to match
                    # pseudo type 'unknown'
                    if not image["types"]:
                        image["types"] = ["unknown"]
                    else:
                        image["types"] = list(map(str.lower, image["types"]))
                    if self.restrict_types:
                        # only keep enabled caa types
                        types = set(image["types"]).intersection(
                            set(self.caa_types))
                    else:
                        types = True
                    if types:
                        if thumbsize is None or is_pdf:
                            url = image["image"]
                        else:
                            url = image["thumbnails"][thumbsize]
                        coverartimage = self.coverartimage_class(
                            url,
                            types=image["types"],
                            is_front=image['front'],
                            comment=image["comment"],
                        )
                        if is_pdf:
                            # thumbnail will be used to "display" PDF in info
                            # dialog
                            thumbnail = self.coverartimage_thumbnail_class(
                                url=image["thumbnails"]['small'],
                                types=image["types"],
                                is_front=image['front'],
                                comment=image["comment"],
                            )
                            self.queue_put(thumbnail)
                            coverartimage.thumbnail = thumbnail
                            # PDFs cannot be saved to tags (as 2014/05/29)
                            coverartimage.can_be_saved_to_tags = False
                        self.queue_put(coverartimage)
                        if config.setting["caa_save_single_front_image"] and \
                                config.setting["save_images_to_files"] and \
                                image["front"]:
                            break

        self.next_in_queue()