clapdat: resolve tag/user names without prefix

This commit is contained in:
Simon
2026-10-17 05:58:53 +00:00
parent 26ef830f6e
commit 813e2ec2ca

View File

@@ -1,7 +1,8 @@
use crate::DbPool; use crate::DbPool;
use crate::api::ClientVersion; use crate::api::ClientVersion;
use crate::providers::{ use crate::providers::{
Provider, build_proxy_url, report_provider_error, requester_or_default, strip_url_scheme, Provider, build_proxy_url, probe_first_archive, report_provider_error, requester_or_default,
slug_dashed, strip_url_scheme,
}; };
use crate::status::*; use crate::status::*;
use crate::util::time::parse_time_to_seconds; use crate::util::time::parse_time_to_seconds;
@@ -149,6 +150,29 @@ impl ClapdatProvider {
} }
} }
/// A free-form query that names a tag or a user goes to that archive
/// (probed on the site; unknown names 404), else keyword search.
async fn resolve_keyword(&self, query: &str, options: &ServerOptions) -> Option<Target> {
let slug = slug_dashed(query);
if slug.is_empty() {
return None;
}
let candidates = [
Target::Tag { slug: slug.clone() },
Target::User { username: slug },
];
let urls: Vec<String> = candidates
.iter()
.filter_map(|t| self.listing_url(t, 1))
.collect();
let mut requester = requester_or_default(options, CHANNEL_ID, "resolve_keyword");
let (index, _) = probe_first_archive(&mut requester, &urls, &format!("{}/", self.url), |body| {
body.contains("/video/")
})
.await?;
candidates.into_iter().nth(index)
}
fn listing_url(&self, target: &Target, page: u16) -> Option<String> { fn listing_url(&self, target: &Target, page: u16) -> Option<String> {
let page = page.max(1); let page = page.max(1);
match target { match target {
@@ -491,7 +515,12 @@ impl Provider for ClapdatProvider {
sort sort
}; };
let query_value = query.unwrap_or_default(); let query_value = query.unwrap_or_default();
let target = self.resolve_target(&query_value, &sort_value); let mut target = self.resolve_target(&query_value, &sort_value);
if let Target::Search { query } = &target {
if let Some(found) = self.resolve_keyword(query, &options).await {
target = found;
}
}
let stubs = match &target { let stubs = match &target {
Target::Search { query } => match self Target::Search { query } => match self