mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-05 00:47:48 +08:00
feat(pool): add table-driven account batch actions
This commit is contained in:
@@ -41,8 +41,9 @@ pub(crate) use self::support::{
|
||||
admin_pool_provider_id_from_path, admin_pool_provider_id_from_scores_path,
|
||||
parse_admin_pool_key_sort, parse_admin_pool_page, parse_admin_pool_page_size,
|
||||
parse_admin_pool_quick_selectors, parse_admin_pool_search, parse_admin_pool_status_filter,
|
||||
AdminPoolKeySort, AdminPoolKeySortDirection, AdminPoolKeySortField,
|
||||
AdminPoolResolveSelectionRequest, ADMIN_POOL_BANNED_KEY_CLEANUP_EMPTY_MESSAGE,
|
||||
parse_admin_pool_status_value, AdminPoolKeySort, AdminPoolKeySortDirection,
|
||||
AdminPoolKeySortField, AdminPoolResolveSelectionRequest,
|
||||
ADMIN_POOL_BANNED_KEY_CLEANUP_EMPTY_MESSAGE,
|
||||
ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL,
|
||||
ADMIN_POOL_PROVIDER_CATALOG_WRITER_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
|
||||
@@ -459,7 +459,7 @@ fn admin_pool_key_cost_exhausted(
|
||||
>= limit
|
||||
}
|
||||
|
||||
fn admin_pool_key_visible_status_filter(
|
||||
pub(super) fn admin_pool_key_visible_status_filter(
|
||||
state: &AdminAppState<'_>,
|
||||
key: &StoredProviderCatalogKey,
|
||||
provider_type: &str,
|
||||
@@ -654,17 +654,22 @@ pub(super) async fn build_admin_pool_list_keys_response(
|
||||
.collect::<Vec<_>>();
|
||||
(keys, total, preloaded_pool_scores_by_key_id)
|
||||
} else if !quick_selectors.is_empty() || sort_by_score {
|
||||
let use_full_search = !quick_selectors.is_empty();
|
||||
let mut keys = state
|
||||
.list_provider_catalog_keys_by_provider_ids(std::slice::from_ref(&provider.id))
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter(|key| {
|
||||
pool_selection::admin_pool_matches_search(
|
||||
state,
|
||||
key,
|
||||
&provider.provider_type,
|
||||
search.as_deref(),
|
||||
)
|
||||
if use_full_search {
|
||||
pool_selection::admin_pool_matches_search(
|
||||
state,
|
||||
key,
|
||||
&provider.provider_type,
|
||||
search.as_deref(),
|
||||
)
|
||||
} else {
|
||||
pool_selection::admin_pool_matches_catalog_search(key, search.as_deref())
|
||||
}
|
||||
})
|
||||
.filter(|key| {
|
||||
quick_selectors.iter().all(|selector| {
|
||||
|
||||
+49
-3
@@ -1,6 +1,9 @@
|
||||
use super::read_keys::admin_pool_key_visible_status_filter;
|
||||
use super::{
|
||||
admin_pool_provider_id_from_path, build_admin_pool_error_response, pool_selection,
|
||||
AdminPoolResolveSelectionRequest, ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL,
|
||||
admin_pool_provider_id_from_path, admin_provider_pool_config, build_admin_pool_error_response,
|
||||
parse_admin_pool_status_value, pool_selection, read_admin_provider_pool_runtime_state,
|
||||
AdminPoolResolveSelectionRequest, AdminProviderPoolRuntimeState,
|
||||
ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL,
|
||||
};
|
||||
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
|
||||
use crate::provider_key_auth::{
|
||||
@@ -49,6 +52,15 @@ pub(super) async fn build_admin_pool_resolve_selection_response(
|
||||
}
|
||||
},
|
||||
};
|
||||
let status = match parse_admin_pool_status_value(payload.status.as_deref()) {
|
||||
Ok(value) => value,
|
||||
Err(detail) => {
|
||||
return Ok(build_admin_pool_error_response(
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
detail,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let Some(provider) = state
|
||||
.read_provider_catalog_providers_by_ids(std::slice::from_ref(&provider_id))
|
||||
@@ -66,13 +78,18 @@ pub(super) async fn build_admin_pool_resolve_selection_response(
|
||||
let search = payload.search.trim();
|
||||
let quick_selectors =
|
||||
admin_provider_pool_pure::admin_pool_sanitize_quick_selectors(payload.quick_selectors);
|
||||
let use_full_search = status != "all" || !quick_selectors.is_empty();
|
||||
|
||||
let mut keys = state
|
||||
.list_provider_catalog_keys_by_provider_ids(std::slice::from_ref(&provider.id))
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter(|key| {
|
||||
pool_selection::admin_pool_matches_search(state, key, &provider_type, Some(search))
|
||||
if use_full_search {
|
||||
pool_selection::admin_pool_matches_search(state, key, &provider_type, Some(search))
|
||||
} else {
|
||||
pool_selection::admin_pool_matches_catalog_search(key, Some(search))
|
||||
}
|
||||
})
|
||||
.filter(|key| {
|
||||
quick_selectors.is_empty()
|
||||
@@ -87,6 +104,35 @@ pub(super) async fn build_admin_pool_resolve_selection_response(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if status != "all" {
|
||||
let pool_config = admin_provider_pool_config(&provider);
|
||||
let key_ids = keys.iter().map(|key| key.id.clone()).collect::<Vec<_>>();
|
||||
let runtime = match pool_config.as_ref() {
|
||||
Some(pool_config) if !key_ids.is_empty() => {
|
||||
read_admin_provider_pool_runtime_state(
|
||||
state.runtime_state(),
|
||||
&provider.id,
|
||||
&key_ids,
|
||||
pool_config,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
}
|
||||
_ => AdminProviderPoolRuntimeState::default(),
|
||||
};
|
||||
let now_unix_secs = admin_provider_pool_pure::admin_pool_now_unix_secs();
|
||||
keys.retain(|key| {
|
||||
admin_pool_key_visible_status_filter(
|
||||
state,
|
||||
key,
|
||||
&provider_type,
|
||||
pool_config.as_ref(),
|
||||
&runtime,
|
||||
now_unix_secs,
|
||||
) == status
|
||||
});
|
||||
}
|
||||
|
||||
keys.sort_by(|left, right| {
|
||||
left.internal_priority
|
||||
.cmp(&right.internal_priority)
|
||||
|
||||
@@ -60,6 +60,19 @@ pub(super) fn admin_pool_matches_search(
|
||||
admin_provider_pool_pure::admin_pool_matches_search(key, search, oauth_plan_type.as_deref())
|
||||
}
|
||||
|
||||
pub(super) fn admin_pool_matches_catalog_search(
|
||||
key: &StoredProviderCatalogKey,
|
||||
search: Option<&str>,
|
||||
) -> bool {
|
||||
let Some(search) = search else {
|
||||
return true;
|
||||
};
|
||||
let search = admin_pool_normalize_text(search);
|
||||
search.is_empty()
|
||||
|| admin_pool_normalize_text(&key.name).contains(&search)
|
||||
|| admin_pool_normalize_text(&key.id).contains(&search)
|
||||
}
|
||||
|
||||
pub(super) fn admin_pool_key_is_known_banned(key: &StoredProviderCatalogKey) -> bool {
|
||||
admin_provider_pool_pure::admin_pool_key_is_known_banned(key)
|
||||
}
|
||||
|
||||
@@ -102,10 +102,12 @@ pub(crate) fn parse_admin_pool_quick_selectors(query: Option<&str>) -> Vec<Strin
|
||||
}
|
||||
|
||||
pub(crate) fn parse_admin_pool_status_filter(query: Option<&str>) -> Result<String, String> {
|
||||
let value = query_param_value(query, "status")
|
||||
.unwrap_or_else(|| "all".to_string())
|
||||
.trim()
|
||||
.to_ascii_lowercase();
|
||||
let value = query_param_value(query, "status");
|
||||
parse_admin_pool_status_value(value.as_deref())
|
||||
}
|
||||
|
||||
pub(crate) fn parse_admin_pool_status_value(value: Option<&str>) -> Result<String, String> {
|
||||
let value = value.unwrap_or("all").trim().to_ascii_lowercase();
|
||||
match value.as_str() {
|
||||
"all"
|
||||
| "available"
|
||||
|
||||
Reference in New Issue
Block a user