fix(musicseerr): enhance Tubidy search with query variations and censorship handling
Build and Push Docker Images / deploy (push) Blocked by required conditions
Details
Build and Push Docker Images / build (api) (push) Successful in 1m10s
Details
Build and Push Docker Images / build (nextgen) (push) Successful in 7m15s
Details
Build and Push Docker Images / build (web) (push) Successful in 2m4s
Details
Build and Push Docker Images / build (worker) (push) Has been cancelled
Details
Build and Push Docker Images / build (musicseerr) (push) Has been cancelled
Details
Build and Push Docker Images / deploy (push) Blocked by required conditions
Details
Build and Push Docker Images / build (api) (push) Successful in 1m10s
Details
Build and Push Docker Images / build (nextgen) (push) Successful in 7m15s
Details
Build and Push Docker Images / build (web) (push) Successful in 2m4s
Details
Build and Push Docker Images / build (worker) (push) Has been cancelled
Details
Build and Push Docker Images / build (musicseerr) (push) Has been cancelled
Details
This commit is contained in:
parent
0bf96f0213
commit
f3779f00cd
|
|
@ -96,6 +96,7 @@ def scrape_tubidy_link(url: str, proxy_url: str) -> str:
|
||||||
def search_tubidy(query: str, proxy_url: str) -> list:
|
def search_tubidy(query: str, proxy_url: str) -> list:
|
||||||
"""
|
"""
|
||||||
Searches Tubidy for the query and returns a list of results with ID, title, and link.
|
Searches Tubidy for the query and returns a list of results with ID, title, and link.
|
||||||
|
Includes robust fallback variations if the initial search returns no results.
|
||||||
"""
|
"""
|
||||||
proxies = {"http": proxy_url, "https": proxy_url} if proxy_url else None
|
proxies = {"http": proxy_url, "https": proxy_url} if proxy_url else None
|
||||||
headers = {
|
headers = {
|
||||||
|
|
@ -115,16 +116,15 @@ def search_tubidy(query: str, proxy_url: str) -> list:
|
||||||
response = cf_requests.get(search_url, headers=headers, params=params, proxies=proxies, impersonate="chrome", timeout=15)
|
response = cf_requests.get(search_url, headers=headers, params=params, proxies=proxies, impersonate="chrome", timeout=15)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
soup = BeautifulSoup(response.text, "html.parser")
|
def parse_results(html: str) -> list:
|
||||||
results = []
|
soup = BeautifulSoup(html, "html.parser")
|
||||||
|
results_list = []
|
||||||
for media_body in soup.find_all("div", class_="media-body"):
|
for media_body in soup.find_all("div", class_="media-body"):
|
||||||
a_tag = media_body.find("a")
|
a_tag = media_body.find("a")
|
||||||
if a_tag:
|
if a_tag:
|
||||||
href = a_tag.get("href")
|
href = a_tag.get("href")
|
||||||
if href:
|
if href:
|
||||||
title = a_tag.get("aria-label") or a_tag.text.strip()
|
title = a_tag.get("aria-label") or a_tag.text.strip()
|
||||||
# Extract ID from /watch/content_id
|
|
||||||
match = re.search(r'/watch/([^/]+)', href)
|
match = re.search(r'/watch/([^/]+)', href)
|
||||||
content_id = match.group(1) if match else None
|
content_id = match.group(1) if match else None
|
||||||
link = href
|
link = href
|
||||||
|
|
@ -134,12 +134,65 @@ def search_tubidy(query: str, proxy_url: str) -> list:
|
||||||
link = f"{endpoint}{href}"
|
link = f"{endpoint}{href}"
|
||||||
|
|
||||||
if content_id:
|
if content_id:
|
||||||
results.append({
|
results_list.append({
|
||||||
"id": content_id,
|
"id": content_id,
|
||||||
"title": title,
|
"title": title,
|
||||||
"link": link
|
"link": link
|
||||||
})
|
})
|
||||||
|
return results_list
|
||||||
|
|
||||||
|
results = parse_results(response.text)
|
||||||
|
if results:
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
# Fallback query variations if first search yielded no results
|
||||||
|
variations = []
|
||||||
|
|
||||||
|
# Variation 1: Clean basic symbols and parentheticals
|
||||||
|
clean1 = re.sub(r'[\(\[][^\)\]]*[\)\]]', '', query)
|
||||||
|
clean1 = clean1.replace("-", " ")
|
||||||
|
clean1 = re.sub(r'\s+', ' ', clean1).strip()
|
||||||
|
variations.append(clean1)
|
||||||
|
|
||||||
|
# Variation 2: Clean and also remove feat/ft
|
||||||
|
clean2 = re.sub(r'(?i)\b(feat|ft)\.?\b.*$', '', clean1)
|
||||||
|
clean2 = re.sub(r'[^\w\s]', '', clean2)
|
||||||
|
clean2 = re.sub(r'\s+', ' ', clean2).strip()
|
||||||
|
variations.append(clean2)
|
||||||
|
|
||||||
|
# Variation 3: Handle censored words (e.g. fucked -> f*cked, fuck -> f*ck)
|
||||||
|
if "fucked" in clean2.lower() or "fuck" in clean2.lower():
|
||||||
|
clean3 = re.sub(r'(?i)\bfucked\b', 'f*cked', clean2)
|
||||||
|
clean3 = re.sub(r'(?i)\bfuck\b', 'f*ck', clean3)
|
||||||
|
variations.append(clean3)
|
||||||
|
|
||||||
|
# Variation 4: Try just the artist and the first 2 words of the title
|
||||||
|
parts = query.split(" - ", 1)
|
||||||
|
if len(parts) == 2:
|
||||||
|
artist = re.sub(r'[^\w\s]', '', parts[0]).strip()
|
||||||
|
title_words = re.sub(r'[^\w\s]', '', parts[1]).strip().split()
|
||||||
|
if len(title_words) > 1:
|
||||||
|
clean4 = f"{artist} {' '.join(title_words[:1])}"
|
||||||
|
variations.append(clean4)
|
||||||
|
|
||||||
|
# Try each variation in order
|
||||||
|
for var in variations:
|
||||||
|
var = var.strip()
|
||||||
|
if not var or var == query:
|
||||||
|
continue
|
||||||
|
logger.info(f"Retrying Tubidy search with variation: '{var}'")
|
||||||
|
params["q"] = var
|
||||||
|
try:
|
||||||
|
response = cf_requests.get(search_url, headers=headers, params=params, proxies=proxies, impersonate="chrome", timeout=15)
|
||||||
|
response.raise_for_status()
|
||||||
|
new_results = parse_results(response.text)
|
||||||
|
if new_results:
|
||||||
|
logger.info(f"Found {len(new_results)} results for variation '{var}'")
|
||||||
|
return new_results
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Variation search for '{var}' failed: {e}")
|
||||||
|
|
||||||
|
return []
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to search Tubidy: {e}")
|
logger.error(f"Failed to search Tubidy: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue