mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2025-04-15 18:21:58 +03:00
added external service for meta retrieve
This commit is contained in:
parent
f320fa2d62
commit
1b9b1d2bb5
76
akarpov/music/services/external.py
Normal file
76
akarpov/music/services/external.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
import requests
|
||||
from typing import Optional, Dict, Any
|
||||
import structlog
|
||||
from django.conf import settings
|
||||
from functools import wraps
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class ExternalServiceClient:
|
||||
def __init__(self):
|
||||
self.base_url = getattr(settings, 'MUSIC_EXTERNAL_SERVICE_URL', None)
|
||||
|
||||
def _make_request(self, endpoint: str, params: Dict = None, **kwargs) -> Optional[Dict]:
|
||||
if not self.base_url:
|
||||
return None
|
||||
|
||||
url = f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
try:
|
||||
response = requests.post(url, params=params, **kwargs)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(
|
||||
"External service request failed",
|
||||
error=str(e),
|
||||
endpoint=endpoint,
|
||||
params=params
|
||||
)
|
||||
return None
|
||||
|
||||
def get_spotify_info(self, track_name: str) -> Optional[Dict[str, Any]]:
|
||||
return self._make_request(
|
||||
"/spotify/search",
|
||||
params={"query": track_name}
|
||||
)
|
||||
|
||||
def translate_text(self, text: str, source_lang: str = "auto", target_lang: str = "en") -> Optional[str]:
|
||||
response = self._make_request(
|
||||
"/translation/translate",
|
||||
json={
|
||||
"text": text,
|
||||
"source_lang": source_lang,
|
||||
"target_lang": target_lang
|
||||
}
|
||||
)
|
||||
return response.get("translated_text") if response else None
|
||||
|
||||
|
||||
def external_service_fallback(fallback_func):
|
||||
"""Decorator to try external service first, then fall back to local implementation"""
|
||||
|
||||
@wraps(fallback_func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if not hasattr(settings, 'MUSIC_EXTERNAL_SERVICE_URL') or not settings.MUSIC_EXTERNAL_SERVICE_URL:
|
||||
return fallback_func(*args, **kwargs)
|
||||
|
||||
client = ExternalServiceClient()
|
||||
try:
|
||||
if fallback_func.__name__ == "get_spotify_info":
|
||||
result = client.get_spotify_info(args[1]) # args[1] is track_name
|
||||
elif fallback_func.__name__ == "safe_translate":
|
||||
result = client.translate_text(args[0]) # args[0] is text
|
||||
|
||||
if result:
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"External service failed, falling back to local implementation",
|
||||
error=str(e),
|
||||
function=fallback_func.__name__
|
||||
)
|
||||
|
||||
return fallback_func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
|
@ -4,6 +4,11 @@
|
|||
import requests
|
||||
import spotipy
|
||||
|
||||
from akarpov.music.services.external import (
|
||||
ExternalServiceClient,
|
||||
external_service_fallback,
|
||||
)
|
||||
|
||||
try:
|
||||
from deep_translator import GoogleTranslator
|
||||
except requests.exceptions.JSONDecodeError:
|
||||
|
@ -76,6 +81,7 @@ def spotify_search(name: str, session: spotipy.Spotify, search_type="track"):
|
|||
return res
|
||||
|
||||
|
||||
@external_service_fallback
|
||||
def get_spotify_info(name: str, session: spotipy.Spotify) -> dict:
|
||||
info = {
|
||||
"album_name": "",
|
||||
|
@ -379,29 +385,43 @@ def save_author_image(author, image_path):
|
|||
print(f"Error saving author image: {str(e)}")
|
||||
|
||||
|
||||
def safe_translate(text):
|
||||
@external_service_fallback
|
||||
def safe_translate(text: str) -> str:
|
||||
try:
|
||||
translated = GoogleTranslator(source="auto", target="en").translate(text)
|
||||
return slugify(translated)
|
||||
except Exception as e:
|
||||
print(f"Error translating text: {str(e)}")
|
||||
print(f"Translation failed: {str(e)}")
|
||||
return slugify(text)
|
||||
|
||||
|
||||
def search_all_platforms(track_name: str) -> dict:
|
||||
print(track_name)
|
||||
# session = spotipy.Spotify(
|
||||
# auth_manager=spotipy.SpotifyClientCredentials(
|
||||
# client_id=settings.MUSIC_SPOTIFY_ID,
|
||||
# client_secret=settings.MUSIC_SPOTIFY_SECRET,
|
||||
# )
|
||||
# )
|
||||
# spotify_info = get_spotify_info(track_name, session)
|
||||
spotify_info = {} # TODO: add proxy for info retrieve
|
||||
|
||||
if settings.MUSIC_EXTERNAL_SERVICE_URL:
|
||||
# Use external service if configured
|
||||
client = ExternalServiceClient()
|
||||
spotify_info = client.get_spotify_info(track_name) or {}
|
||||
else:
|
||||
# Local implementation fallback
|
||||
try:
|
||||
session = spotipy.Spotify(
|
||||
auth_manager=SpotifyClientCredentials(
|
||||
client_id=settings.MUSIC_SPOTIFY_ID,
|
||||
client_secret=settings.MUSIC_SPOTIFY_SECRET,
|
||||
)
|
||||
)
|
||||
spotify_info = get_spotify_info(track_name, session)
|
||||
except Exception as e:
|
||||
print("Local Spotify implementation failed", error=str(e))
|
||||
spotify_info = {}
|
||||
|
||||
yandex_info = search_yandex(track_name)
|
||||
|
||||
if "album_image_path" in spotify_info and "album_image_path" in yandex_info:
|
||||
os.remove(yandex_info["album_image_path"])
|
||||
|
||||
# Combine artist information
|
||||
combined_artists = set()
|
||||
for artist in spotify_info.get("artists", []) + yandex_info.get("artists", []):
|
||||
normalized_artist = normalize_text(artist)
|
||||
|
@ -410,12 +430,13 @@ def search_all_platforms(track_name: str) -> dict:
|
|||
for existing_artist in combined_artists
|
||||
):
|
||||
combined_artists.add(normalized_artist)
|
||||
genre = spotify_info.get("genre") or yandex_info.get("genre")
|
||||
if type(genre) is list:
|
||||
genre = sorted(genre, key=lambda x: len(x))
|
||||
genre = genre[0]
|
||||
|
||||
track_info = {
|
||||
# Process genre information
|
||||
genre = spotify_info.get("genre") or yandex_info.get("genre")
|
||||
if isinstance(genre, list) and genre:
|
||||
genre = sorted(genre, key=len)[0]
|
||||
|
||||
return {
|
||||
"album_name": spotify_info.get("album_name")
|
||||
or yandex_info.get("album_name", ""),
|
||||
"release": spotify_info.get("release") or yandex_info.get("release", ""),
|
||||
|
@ -425,5 +446,3 @@ def search_all_platforms(track_name: str) -> dict:
|
|||
"album_image": spotify_info.get("album_image_path")
|
||||
or yandex_info.get("album_image_path", None),
|
||||
}
|
||||
|
||||
return track_info
|
||||
|
|
|
@ -715,6 +715,9 @@
|
|||
LAST_FM_API_KEY = env("LAST_FM_API_KET", default="")
|
||||
LAST_FM_SECRET = env("LAST_FM_SECRET", default="")
|
||||
|
||||
# EXTERNAL
|
||||
MUSIC_EXTERNAL_SERVICE_URL = env("MUSIC_EXTERNAL_SERVICE_URL", default="")
|
||||
|
||||
# ROBOTS
|
||||
# ------------------------------------------------------------------------------
|
||||
ROBOTS_USE_SITEMAP = True
|
||||
|
|
Loading…
Reference in New Issue
Block a user