def _do_mb_search(entity, query='', fields={}, limit=None, offset=None, strict=False): """Perform a full-text search on the MusicBrainz search server. `query` is a lucene query string when no fields are set, but is escaped when any fields are given. `fields` is a dictionary of key/value query parameters. They keys in `fields` must be valid for the given entity type. """ # Encode the query terms as a Lucene query string. query_parts = [] if query: clean_query = util._unicode(query) if fields: clean_query = re.sub(LUCENE_SPECIAL, r'\\\1', clean_query) if strict: query_parts.append('"%s"' % clean_query) else: query_parts.append(clean_query.lower()) else: query_parts.append(clean_query) for key, value in fields.items(): # Ensure this is a valid search field. if key not in VALID_SEARCH_FIELDS[entity]: raise InvalidSearchFieldError( '%s is not a valid search field for %s' % (key, entity) ) elif key == "puid": warn("PUID support was removed from server\n" "the 'puid' field is ignored", Warning, stacklevel=2) # Escape Lucene's special characters. value = util._unicode(value) value = re.sub(LUCENE_SPECIAL, r'\\\1', value) if value: if strict: query_parts.append('%s:"%s"' % (key, value)) else: value = value.lower() # avoid AND / OR query_parts.append('%s:(%s)' % (key, value)) if strict: full_query = ' AND '.join(query_parts).strip() else: full_query = ' '.join(query_parts).strip() if not full_query: raise ValueError('at least one query term is required') # Additional parameters to the search. params = {'query': full_query} if limit: params['limit'] = str(limit) if offset: params['offset'] = str(offset) return _do_mb_query(entity, '', [], params)
def _do_mb_search(entity, query='', fields={}, limit=None, offset=None, strict=False): """Perform a full-text search on the MusicBrainz search server. `query` is a lucene query string when no fields are set, but is escaped when any fields are given. `fields` is a dictionary of key/value query parameters. They keys in `fields` must be valid for the given entity type. """ # Encode the query terms as a Lucene query string. query_parts = [] if query: clean_query = util._unicode(query) if fields: clean_query = re.sub(r'([+\-&|!(){}\[\]\^"~*?:\\])', r'\\\1', clean_query) if strict: query_parts.append('"%s"' % clean_query) else: query_parts.append(clean_query.lower()) else: query_parts.append(clean_query) for key, value in fields.items(): # Ensure this is a valid search field. if key not in VALID_SEARCH_FIELDS[entity]: raise InvalidSearchFieldError( '%s is not a valid search field for %s' % (key, entity) ) elif key == "puid": warn("PUID support was removed from server\n" "the 'puid' field is ignored", DeprecationWarning, stacklevel=2) # Escape Lucene's special characters. value = util._unicode(value) value = re.sub(r'([+\-&|!(){}\[\]\^"~*?:\\\/])', r'\\\1', value) if value: if strict: query_parts.append('%s:"%s"' % (key, value)) else: value = value.lower() # avoid AND / OR query_parts.append('%s:(%s)' % (key, value)) if strict: full_query = ' AND '.join(query_parts).strip() else: full_query = ' '.join(query_parts).strip() if not full_query: raise ValueError('at least one query term is required') # Additional parameters to the search. params = {'query': full_query} if limit: params['limit'] = str(limit) if offset: params['offset'] = str(offset) return _do_mb_query(entity, '', [], params)
def _do_mb_search(entity, query="", fields={}, limit=None, offset=None, strict=False): """Perform a full-text search on the MusicBrainz search server. `query` is a lucene query string when no fields are set, but is escaped when any fields are given. `fields` is a dictionary of key/value query parameters. They keys in `fields` must be valid for the given entity type. """ # Encode the query terms as a Lucene query string. query_parts = [] if query: clean_query = util._unicode(query) if fields: clean_query = re.sub(r'([+\-&|!(){}\[\]\^"~*?:\\])', r"\\\1", clean_query) if strict: query_parts.append('"%s"' % clean_query) else: query_parts.append(clean_query.lower()) else: query_parts.append(clean_query) for key, value in fields.items(): # Ensure this is a valid search field. if key not in VALID_SEARCH_FIELDS[entity]: raise InvalidSearchFieldError("%s is not a valid search field for %s" % (key, entity)) # Escape Lucene's special characters. value = util._unicode(value) value = re.sub(r'([+\-&|!(){}\[\]\^"~*?:\\\/])', r"\\\1", value) if value: if strict: query_parts.append('%s:"%s"' % (key, value)) else: value = value.lower() # avoid AND / OR query_parts.append("%s:(%s)" % (key, value)) if strict: full_query = " AND ".join(query_parts).strip() else: full_query = " ".join(query_parts).strip() if not full_query: raise ValueError("at least one query term is required") # Additional parameters to the search. params = {"query": full_query} if limit: params["limit"] = str(limit) if offset: params["offset"] = str(offset) return _do_mb_query(entity, "", [], params)
def _caa_request(mbid, imageid=None, size=None, entitytype="release"): """ Make a CAA request. :param imageid: ``front``, ``back`` or a number from the listing obtained with :meth:`get_image_list`. :type imageid: str :param size: "250", "500", "1200" :type size: str or None :param entitytype: ``release`` or ``release-group`` :type entitytype: str """ # Construct the full URL for the request, including hostname and # query string. path = [entitytype, mbid] if imageid and size: path.append("%s-%s" % (imageid, size)) elif imageid: path.append(imageid) url = compat.urlunparse(( 'http', hostname, '/%s' % '/'.join(path), '', '', '' )) musicbrainz._log.debug("GET request for %s" % (url, )) # Set up HTTP request handler and URL opener. httpHandler = compat.HTTPHandler(debuglevel=0) handlers = [httpHandler] opener = compat.build_opener(*handlers) # Make request. req = musicbrainz._MusicbrainzHttpRequest("GET", url, None) # Useragent isn't needed for CAA, but we'll add it if it exists if musicbrainz._useragent != "": req.add_header('User-Agent', musicbrainz._useragent) musicbrainz._log.debug("requesting with UA %s" % musicbrainz._useragent) resp = musicbrainz._safe_read(opener, req, None) # TODO: The content type declared by the CAA for JSON files is # 'applicaiton/octet-stream'. This is not useful to detect whether the # content is JSON, so default to decoding JSON if no imageid was supplied. # http://tickets.musicbrainz.org/browse/CAA-75 if imageid: # If we asked for an image, return the image return resp else: # Otherwise it's json data = _unicode(resp) return json.loads(data)
def _caa_request(mbid, imageid=None, size=None, entitytype="release"): """ Make a CAA request. :param imageid: ``front``, ``back`` or a number from the listing obtained with :meth:`get_image_list`. :type imageid: str :param size: "250", "500", "1200" :type size: str or None :param entitytype: ``release`` or ``release-group`` :type entitytype: str """ # Construct the full URL for the request, including hostname and # query string. path = [entitytype, mbid] if imageid and size: path.append("%s-%s" % (imageid, size)) elif imageid: path.append(imageid) url = compat.urlunparse( ('http', hostname, '/%s' % '/'.join(path), '', '', '')) musicbrainz._log.debug("GET request for %s" % (url, )) # Set up HTTP request handler and URL opener. httpHandler = compat.HTTPHandler(debuglevel=0) handlers = [httpHandler] opener = compat.build_opener(*handlers) # Make request. req = musicbrainz._MusicbrainzHttpRequest("GET", url, None) # Useragent isn't needed for CAA, but we'll add it if it exists if musicbrainz._useragent != "": req.add_header('User-Agent', musicbrainz._useragent) musicbrainz._log.debug("requesting with UA %s" % musicbrainz._useragent) resp = musicbrainz._safe_read(opener, req, None) # TODO: The content type declared by the CAA for JSON files is # 'applicaiton/octet-stream'. This is not useful to detect whether the # content is JSON, so default to decoding JSON if no imageid was supplied. # http://tickets.musicbrainz.org/browse/CAA-75 if imageid: # If we asked for an image, return the image return resp else: # Otherwise it's json data = _unicode(resp) return json.loads(data)