cleaned up search
This commit is contained in:
parent
ab7f414125
commit
67b4a3bc65
@ -2,6 +2,7 @@ import logging
|
||||
import random
|
||||
from copy import copy
|
||||
from typing import Optional, Union, Type, Dict, Set, List
|
||||
import threading
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
@ -25,52 +26,66 @@ from ..utils import shared
|
||||
from ..utils.support_classes import Query, DownloadResult, DefaultTarget
|
||||
|
||||
|
||||
class Page:
|
||||
class Page(threading.Thread):
|
||||
"""
|
||||
This is an abstract class, laying out the
|
||||
functionality for every other class fetching something
|
||||
"""
|
||||
CONNECTION: Connection
|
||||
|
||||
API_SESSION: requests.Session = requests.Session()
|
||||
API_SESSION.proxies = shared.proxies
|
||||
TIMEOUT = 5
|
||||
POST_TIMEOUT = TIMEOUT
|
||||
TRIES = 5
|
||||
LOGGER = logging.getLogger("this shouldn't be used")
|
||||
|
||||
SOURCE_TYPE: SourcePages
|
||||
LOGGER = logging.getLogger("this shouldn't be used")
|
||||
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
@classmethod
|
||||
def get_soup_from_response(cls, r: requests.Response) -> BeautifulSoup:
|
||||
return BeautifulSoup(r.content, "html.parser")
|
||||
|
||||
@classmethod
|
||||
def search(cls, query: Query) -> Options:
|
||||
# to search stuff
|
||||
def search(self, query: Query) -> List[DatabaseObject]:
|
||||
results = []
|
||||
|
||||
for default_query in query.default_search:
|
||||
results.extend(cls._raw_search(default_query))
|
||||
if query.is_raw:
|
||||
for search_query in query.default_search:
|
||||
results.extend(self.general_search(search_query))
|
||||
return results
|
||||
|
||||
return Options(results)
|
||||
|
||||
@classmethod
|
||||
def _raw_search(cls, query: str) -> Options:
|
||||
"""
|
||||
# The Query
|
||||
You can define a new parameter with "#",
|
||||
the letter behind it defines the *type* of parameter, followed by a space
|
||||
"#a Psychonaut 4 #r Tired, Numb and #t Drop by Drop"
|
||||
if no # is in the query it gets treated as "unspecified query"
|
||||
|
||||
# Functionality
|
||||
Returns the best matches from this page for the query, passed in.
|
||||
|
||||
:param query:
|
||||
:return possible_music_objects:
|
||||
"""
|
||||
|
||||
music_object = query.music_object
|
||||
|
||||
search_functions = {
|
||||
Song: self.song_search,
|
||||
Album: self.album_search,
|
||||
Artist: self.artist_search,
|
||||
Label: self.label_search
|
||||
}
|
||||
|
||||
if type(music_object) in search_functions:
|
||||
r = search_functions[type(music_object)](music_object)
|
||||
if len(r) > 0:
|
||||
return r
|
||||
|
||||
r = []
|
||||
for default_query in query.default_search:
|
||||
results.extend(self.general_search(default_query))
|
||||
|
||||
return results
|
||||
|
||||
def general_search(self, search_query: str) -> List[DatabaseObject]:
|
||||
return []
|
||||
|
||||
def label_search(self, label: Label) -> List[Label]:
|
||||
return []
|
||||
|
||||
def artist_search(self, artist: Artist) -> List[Artist]:
|
||||
return []
|
||||
|
||||
def album_search(self, album: Album) -> List[Album]:
|
||||
return []
|
||||
|
||||
def song_search(self, song: Song) -> List[Song]:
|
||||
return []
|
||||
|
||||
|
||||
@classmethod
|
||||
def fetch_details(cls, music_object: Union[Song, Album, Artist, Label], stop_at_level: int = 1) -> DatabaseObject:
|
||||
|
@ -23,6 +23,17 @@ from ..objects import (
|
||||
)
|
||||
|
||||
|
||||
ALBUM_TYPE_MAP: Dict[str, AlbumType] = defaultdict(lambda: AlbumType.OTHER, {
|
||||
"Full-length": AlbumType.STUDIO_ALBUM,
|
||||
"Single": AlbumType.SINGLE,
|
||||
"EP": AlbumType.EP,
|
||||
"Demo": AlbumType.DEMO,
|
||||
"Video": AlbumType.OTHER,
|
||||
"Live album": AlbumType.LIVE_ALBUM,
|
||||
"Compilation": AlbumType.COMPILATION_ALBUM
|
||||
})
|
||||
|
||||
|
||||
class EncyclopaediaMetallum(Page):
|
||||
CONNECTION: Connection = Connection(
|
||||
host="https://www.metal-archives.com/",
|
||||
@ -30,36 +41,14 @@ class EncyclopaediaMetallum(Page):
|
||||
)
|
||||
|
||||
SOURCE_TYPE = SourcePages.ENCYCLOPAEDIA_METALLUM
|
||||
|
||||
ALBUM_TYPE_MAP: Dict[str, AlbumType] = defaultdict(lambda: AlbumType.OTHER, {
|
||||
"Full-length": AlbumType.STUDIO_ALBUM,
|
||||
"Single": AlbumType.SINGLE,
|
||||
"EP": AlbumType.EP,
|
||||
"Demo": AlbumType.DEMO,
|
||||
"Video": AlbumType.OTHER,
|
||||
"Live album": AlbumType.LIVE_ALBUM,
|
||||
"Compilation": AlbumType.COMPILATION_ALBUM
|
||||
})
|
||||
|
||||
LOGGER = ENCYCLOPAEDIA_METALLUM_LOGGER
|
||||
|
||||
@classmethod
|
||||
def _raw_search(cls, query: str) -> Options:
|
||||
query_obj = cls.Query(query)
|
||||
|
||||
if query_obj.is_raw:
|
||||
return cls.simple_search(query_obj)
|
||||
return cls.advanced_search(query_obj)
|
||||
|
||||
@classmethod
|
||||
def advanced_search(cls, query: Query) -> Options:
|
||||
if query.song is not None:
|
||||
return Options(cls.search_for_song(query=query))
|
||||
if query.album is not None:
|
||||
return Options(cls.search_for_album(query=query))
|
||||
if query.artist is not None:
|
||||
return Options(cls.search_for_artist(query=query))
|
||||
return Options
|
||||
|
||||
def __init__(self):
|
||||
self.connection: Connection = Connection(
|
||||
host="https://www.metal-archives.com/",
|
||||
logger=ENCYCLOPAEDIA_METALLUM_LOGGER
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def search_for_song(cls, query: Query) -> List[Song]:
|
||||
@ -123,7 +112,7 @@ class EncyclopaediaMetallum(Page):
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def simple_search(cls, query: Query) -> List[Artist]:
|
||||
def _raw_search(cls, query: str) -> Options:
|
||||
"""
|
||||
Searches the default endpoint from metal archives, which intern searches only
|
||||
for bands, but it is the default, thus I am rolling with it
|
||||
@ -132,12 +121,12 @@ class EncyclopaediaMetallum(Page):
|
||||
|
||||
r = cls.CONNECTION.get(endpoint.format(query=query))
|
||||
if r is None:
|
||||
return []
|
||||
return Options()
|
||||
|
||||
return [
|
||||
return Options([
|
||||
cls.get_artist_from_json(artist_html=raw_artist[0], genre=raw_artist[1], country=raw_artist[2])
|
||||
for raw_artist in r.json()['aaData']
|
||||
]
|
||||
])
|
||||
|
||||
@classmethod
|
||||
def get_artist_from_json(cls, artist_html=None, genre=None, country=None) -> Artist:
|
||||
|
@ -9,7 +9,11 @@ class Query:
|
||||
music_object: DatabaseObject = None
|
||||
) -> None:
|
||||
self.raw_query: str = raw_query
|
||||
self.music_object: Optional[DatabaseObject] = None
|
||||
self.music_object: Optional[DatabaseObject] = music_object
|
||||
|
||||
@property
|
||||
def is_raw(self) -> bool:
|
||||
return self.music_object is None
|
||||
|
||||
@property
|
||||
def default_search(self) -> List[str]:
|
||||
|
Loading…
Reference in New Issue
Block a user