Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various search fixes #877

Merged
merged 4 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions nowplaying/artistextras/discogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
''' start of support of discogs '''

import logging
import logging.config
import logging.handlers
import socket

import requests.exceptions
Expand All @@ -22,7 +20,6 @@ def __init__(self, config=None, qsettings=None):
super().__init__(config=config, qsettings=qsettings)
self.displayname = "Discogs"
self.client = None
self.version = config.version

def _get_apikey(self):
apikey = self.config.cparser.value('discogs/apikey')
Expand Down Expand Up @@ -56,9 +53,20 @@ def _find_discogs_artist_releaselist(self, metadata):
if len(discogs_website) == 1:
artistnum = discogs_website[0].split('/')[-1]
artist = self.client.artist(artistnum)
artistname = artist.name
artistname = str(artist.name)
logging.debug('Found a singular discogs artist URL using %s instead of %s',
artistname, metadata['artist'])
elif len(discogs_website) > 1:
for website in discogs_website:
artistnum = website.split('/')[-1]
artist = self.client.artist(artistnum)
webartistname = str(artist.name)
if nowplaying.utils.normalize(webartistname) == nowplaying.utils.normalize(
metadata['artist']):
logging.debug(
'Found near exact match discogs artist URL %s using %s instead of %s',
website, webartistname, metadata['artist'])
artistname = webartistname

try:
logging.debug('Fetching %s - %s', artistname, metadata['album'])
Expand Down
11 changes: 7 additions & 4 deletions nowplaying/artistextras/theaudiodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ def _check_artist(self, artdata):
''' is this actually the artist we are looking for? '''
for fieldname in ['strArtist', 'strArtistAlternate']:
if artdata.get(fieldname) and self.fnstr:
normalized = nowplaying.utils.normalize(artdata[fieldname])
normalized = nowplaying.utils.normalize(artdata[fieldname],
sizecheck=4,
nospaces=True)
if normalized and normalized in self.fnstr:
logging.debug('theaudiodb Trusting %s: %s', fieldname, artdata[fieldname])
return True
logging.debug('theaudiodb not Trusting %s vs. %s', self.fnstr,
nowplaying.utils.normalize(artdata.get(fieldname)))
logging.debug(
'theaudiodb not Trusting %s vs. %s', self.fnstr,
nowplaying.utils.normalize(artdata.get(fieldname), sizecheck=4, nospaces=True))
return False

def _handle_extradata(self, extradata, metadata, imagecache): # pylint: disable=too-many-branches
Expand Down Expand Up @@ -140,7 +143,7 @@ def download(self, metadata=None, imagecache=None): # pylint: disable=too-many-
return None

extradata = []
self.fnstr = nowplaying.utils.normalize(metadata['artist'])
self.fnstr = nowplaying.utils.normalize(metadata['artist'], sizecheck=4, nospaces=True)

# if musicbrainz lookup fails, then there likely isn't
# data in theaudiodb that matches.
Expand Down
11 changes: 3 additions & 8 deletions nowplaying/imagecache.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import aiosqlite
import diskcache
import normality
import requests_cache

from PySide6.QtCore import QStandardPaths # pylint: disable=no-name-in-module
Expand Down Expand Up @@ -67,10 +66,6 @@ def __init__(self, sizelimit=1, initialize=False, cachedir=None, stopevent=None)
self.logpath = None
self.stopevent = stopevent

@staticmethod
def _normalize_artist(artist):
return normality.normalize(artist).replace(' ', '')

def setup_sql(self, initialize=False):
''' create the database '''

Expand Down Expand Up @@ -99,7 +94,7 @@ def setup_sql(self, initialize=False):

def random_fetch(self, artist, imagetype):
''' fetch a random row from a cache for the artist '''
normalartist = self._normalize_artist(artist)
normalartist = nowplaying.utils.normalize(artist, sizecheck=0, nospaces=True)
data = None
if not self.databasefile.exists():
self.setup_sql()
Expand Down Expand Up @@ -225,7 +220,7 @@ def fill_queue(self, config, artist, imagetype, urllist):

logging.debug('Putting %s unfiltered for %s/%s', min(len(urllist), maxart), imagetype,
artist)
normalartist = self._normalize_artist(artist)
normalartist = nowplaying.utils.normalize(artist, sizecheck=0, nospaces=True)
for url in random.sample(urllist, min(len(urllist), maxart)):
self.put_db_url(artist=normalartist, imagetype=imagetype, url=url)

Expand Down Expand Up @@ -281,7 +276,7 @@ def put_db_cachekey(self, artist, url, imagetype, cachekey=None):
logging.error('imagecache does not exist yet?')
return

normalartist = self._normalize_artist(artist)
normalartist = nowplaying.utils.normalize(artist, sizecheck=0, nospaces=True)
with sqlite3.connect(self.databasefile, timeout=30) as connection:
connection.row_factory = sqlite3.Row
cursor = connection.cursor()
Expand Down
2 changes: 2 additions & 0 deletions nowplaying/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ def _uniqlists(self):
if self.metadata.get('artistwebsites'):
newlist = []
for url in self.metadata['artistwebsites']:
if 'wikidata' in url:
continue
if 'http:' not in url:
newlist.append(url)
continue
Expand Down
4 changes: 3 additions & 1 deletion nowplaying/musicbrainz.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ def _websites(self, idlist):
'official homepage': 'homepage',
'last.fm': 'lastfm',
'discogs': 'discogs',
'wikidata': 'wikidata'
}

for urlrel in webdata['artist']['url-relation-list']:
Expand All @@ -327,11 +328,12 @@ def _websites(self, idlist):
type=bool) and urlrel['type'] == 'discogs':
sitelist.append(urlrel['target'])
logging.debug('placed %s', dest)
elif urlrel['type'] == 'wikidata':
sitelist.append(urlrel['target'])
elif urlrel['type'] == src and self.config.cparser.value(f'acoustidmb/{dest}',
type=bool):
sitelist.append(urlrel['target'])
logging.debug('placed %s', dest)

return sitelist

def providerinfo(self): # pylint: disable=no-self-use
Expand Down
30 changes: 20 additions & 10 deletions nowplaying/recognition/acoustidmb.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,19 @@ def _fetch_from_acoustid(self, apikey, fingerprint, duration):
return results['results']

def _read_acoustid_tuples(self, metadata, results): # pylint: disable=too-many-branches, too-many-statements, too-many-locals
fnstr = ''
if metadata.get('filename'):
fnstr = nowplaying.utils.normalize(metadata['filename'])
else:
fnstr = ''
fnstr = nowplaying.utils.normalize(metadata['filename'], sizecheck=4, nospaces=True)
if not fnstr:
fnstr = ''

artist = metadata.get('artist')
title = metadata.get('title')
if artist and title and artist in title and len(artist) > 3:
title = title.replace(artist, '')
title = nowplaying.utils.titlestripper_basic(title=title)
artistnstr = nowplaying.utils.normalize(artist)
titlenstr = nowplaying.utils.normalize(title)
artistnstr = nowplaying.utils.normalize(artist, sizecheck=4, nospaces=True)
titlenstr = nowplaying.utils.normalize(title, sizecheck=4, nospaces=True)

if not artistnstr:
artistnstr = ''
Expand Down Expand Up @@ -160,18 +161,21 @@ def _read_acoustid_tuples(self, metadata, results): # pylint: disable=too-many-
albumartist = artist['name']
elif isinstance(artist, str):
albumartist = artist
else:
albumartist = ''
if albumartist == 'Various Artists':
score = score - .10
elif albumartist and nowplaying.utils.normalize(
albumartist) in completenstr:
albumartist, sizecheck=4, nospaces=True) in completenstr:
score = score + .20

title = release['mediums'][0]['tracks'][0]['title']
if release.get('title'):
album = release['title']
else:
album = None
if title and nowplaying.utils.normalize(title) in completenstr:
if title and nowplaying.utils.normalize(title, sizecheck=4,
nospaces=True) in completenstr:
score = score + .10
artistlist = []
artistidlist = []
Expand All @@ -182,11 +186,13 @@ def _read_acoustid_tuples(self, metadata, results): # pylint: disable=too-many-
elif isinstance(trackartist, str):
artistlist.append(trackartist)
if trackartist and artistnstr:
if nowplaying.utils.normalize(trackartist) == artistnstr:
if nowplaying.utils.normalize(trackartist, sizecheck=4,
nospaces=True) == artistnstr:
score = score + .30
else:
score = score - .50
if trackartist and nowplaying.utils.normalize(trackartist) in completenstr:
if trackartist and nowplaying.utils.normalize(
trackartist, sizecheck=4, nospaces=True) in completenstr:
score = score + .10

artist = ' & '.join(artistlist)
Expand Down Expand Up @@ -223,10 +229,14 @@ def _configure_fpcalc(self, fpcalcexe=None): # pylint: disable=too-many-return-
if fpcalcexe and not os.environ.get("FPCALC"):
os.environ.setdefault("FPCALC", fpcalcexe)
os.environ["FPCALC"] = fpcalcexe
elif sys.platform == 'linux':
if pathlib.Path('/usr/bin/fpcalc').exists():
os.environ.setdefault("FPCALC", '/usr/bin/fpcalc')
os.environ["FPCALC"] = '/usr/bin/fpcalc'

try:
fpcalcexe = os.environ["FPCALC"]
except NameError:
except (NameError, KeyError):
logging.error('fpcalc is not configured')
return False

Expand Down
26 changes: 12 additions & 14 deletions nowplaying/trackrequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import re
import sqlite3
import traceback
import typing as t

import aiohttp
import aiosqlite #pylint: disable=import-error
import normality #pylint: disable=import-error

from PySide6.QtCore import Slot, QFile, QFileSystemWatcher, QStandardPaths # pylint: disable=import-error, no-name-in-module
from PySide6.QtWidgets import QComboBox, QHeaderView, QTableWidgetItem # pylint: disable=import-error, no-name-in-module
Expand All @@ -19,7 +19,7 @@
import nowplaying.db
import nowplaying.metadata
from nowplaying.exceptions import PluginVerifyError
from nowplaying.utils import TRANSPARENT_PNG_BIN
import nowplaying.utils

USERREQUEST_TEXT = [
'artist', 'title', 'displayname', 'type', 'playlist', 'username', 'filename', 'user_input',
Expand Down Expand Up @@ -185,12 +185,10 @@ async def get_roulette_dupe_list(self, playlist=None):
return dataset

@staticmethod
def normalize(crazystring):
''' user input needs to be normalized for best case matches '''
if not crazystring:
return ''
if text := normality.normalize(crazystring):
return text.replace(' ', '')
def _normalize(text: t.Optional[str]) -> str:
''' db normalize '''
if text := nowplaying.utils.normalize(text, sizecheck=0, nospaces=True):
return text
return ''

async def add_to_db(self, data):
Expand All @@ -199,8 +197,8 @@ async def add_to_db(self, data):
logging.error('%s does not exist, refusing to add.', self.databasefile)
return

data['normalizedartist'] = self.normalize(data.get('artist', ''))
data['normalizedtitle'] = self.normalize(data.get('title', ''))
data['normalizedartist'] = self._normalize(data.get('artist', ''))
data['normalizedtitle'] = self._normalize(data.get('title', ''))

if data.get('reqid'):
reqid = data['reqid']
Expand Down Expand Up @@ -392,8 +390,8 @@ async def _request_lookup_by_artist_title(self, artist='', title=''):
newdata = await self._get_and_del_request_lookup(sql, datatuple)

if not newdata:
artist = self.normalize(artist)
title = self.normalize(title)
artist = self._normalize(artist)
title = self._normalize(title)
logging.debug('trying normalized artist >%s< / title >%s<', artist, title)
sql = 'SELECT * FROM userrequest WHERE normalizedartist=? AND normalizedtitle=?'
datatuple = artist, title
Expand Down Expand Up @@ -428,7 +426,7 @@ async def get_request(self, metadata):
return None

if not newdata.get('requesterimageraw'):
newdata['requesterimageraw'] = TRANSPARENT_PNG_BIN
newdata['requesterimageraw'] = nowplaying.utils.TRANSPARENT_PNG_BIN

return newdata

Expand Down Expand Up @@ -557,7 +555,7 @@ async def _tenor_request(self, search_terms):

content = {
'imageurl': None,
'image': TRANSPARENT_PNG_BIN,
'image': nowplaying.utils.TRANSPARENT_PNG_BIN,
'keywords': search_terms,
}

Expand Down
33 changes: 21 additions & 12 deletions nowplaying/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import re
import time
import traceback
import typing as t

import jinja2
import normality
Expand Down Expand Up @@ -108,7 +109,7 @@ def generate(self, metadatadict=None):
rendertext = self.template.render(**metadatadict)
else:
rendertext = self.template.render()
except: #pylint: disable=bare-except
except Exception: # pylint: disable=broad-except
for line in traceback.format_exc().splitlines():
logging.error(line)
return rendertext
Expand Down Expand Up @@ -184,9 +185,7 @@ def songpathsubst(config, filename):
newname = filename

if songin := config.cparser.value('quirks/filesubstin'):
songout = config.cparser.value('quirks/filesubstout')
if not songout:
songout = ''
songout = config.cparser.value('quirks/filesubstout') or ''

try:
newname = filename.replace(songin, songout)
Expand All @@ -199,16 +198,26 @@ def songpathsubst(config, filename):
return newname


def normalize(crazystring):
''' take a string and genericize it '''
if not crazystring:
def normalize_text(text: t.Optional[str]) -> t.Optional[str]:
''' take a string and genercize it '''
if not text:
return None
if len(crazystring) < 4:
transtext = text.translate(CUSTOM_TRANSLATE)
if normal := normality.normalize(transtext):
return normal
return transtext


def normalize(text: t.Optional[str], sizecheck: int = 0, nospaces: bool = False) -> t.Optional[str]:
''' genericize string, optionally strip spaces, do a size check '''
if not text:
return None
if len(text) < sizecheck:
return 'TEXT IS TOO SMALL IGNORE'
text = crazystring.translate(CUSTOM_TRANSLATE)
if text := normality.normalize(text):
return text.replace(' ', '')
return None
normaltext = normalize_text(text) or text
if nospaces:
return normaltext.replace(' ', '')
return normaltext


def titlestripper_basic(title=None, title_regex_list=None):
Expand Down
Loading
Loading