feat(uploads): match release groups with MusicBrainz and AcoustID
ci / module boundaries / boundaries (push) Successful in 10s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m30s
ci / api / api (push) Successful in 58s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m1s
ci / db / db (push) Failing after 25s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m36s
ci / ts / ts (packages + web) (push) Failing after 6m3s

This commit is contained in:
mrleo1nid committed 2026-10-29 20:44:59 +03:00
1 parent 1e3a149aef
commit 39bf7d4b70
45 files changed
+4792 -417

No files matched your search

+256
View File
@@ -955,6 +955,68 @@ export interface paths {
patch: operations["updateUploadBatch"];
trace?: never;
};
"/api/v1/admin/uploads/batches/{id}/releases": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
/** Состояние фонового сопоставления пачки с изданиями MusicBrainz */
get: operations["getUploadReleases"];
put?: never;
/** Повторить поиск релиза, при необходимости с уточнённым запросом */
post: operations["searchUploadReleases"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/uploads/batches/{id}/releases/{release_id}/cover": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
release_id: string;
};
cookie?: never;
};
/** Предпросмотр обложки выбранного кандидата из Cover Art Archive */
get: operations["getUploadReleaseCover"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/uploads/batches/{id}/release": {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* Явно применить метаданные и/или обложку выбранного издания
* @description Только к совпавшим редактируемым файлам. Изменившаяся пачка или повторный поиск приводят к 409; одобрение и квота не меняются.
*/
post: operations["applyUploadRelease"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/uploads/review": {
parameters: {
query?: never;
@@ -2343,6 +2405,74 @@ export interface components {
/** Format: uuid */
target_source_id?: string;
};
ReleaseTrack: {
recording_id: string;
title: string;
artist: string;
disc: number;
position: number;
duration_ms: number;
};
ReleaseInfo: {
id: string;
group_id: string;
title: string;
artist: string;
type: string;
date: string;
country: string;
comment: string;
has_cover: boolean;
tracks: components["schemas"]["ReleaseTrack"][];
};
ReleaseCandidate: {
release: components["schemas"]["ReleaseInfo"];
matches: {
/** Format: uuid */
file_id: string;
track_index: number;
confidence: string;
/** @enum {string} */
method?: "metadata" | "acoustid";
}[];
missing: components["schemas"]["ReleaseTrack"][];
/** @description Совпадения отсутствующих дорожек с библиотекой по метаданным и длительности; не подтверждают полную загруженную пачку */
existing: components["schemas"]["ReleaseTrack"][];
unmatched: string[];
matched: number;
total: number;
complete: boolean;
confidence: string;
};
UploadReleaseGroup: {
/** Format: uuid */
id: string;
artist: string;
album: string;
file_ids: string[];
has_cover: boolean;
state: string;
};
UploadReleaseReport: {
/** Format: uuid */
group_id?: string;
groups?: components["schemas"]["UploadReleaseGroup"][];
audio_available?: boolean;
audio_results?: {
/** Format: uuid */
file_id: string;
/** @enum {string} */
state: "matched" | "ambiguous" | "not_found" | "unavailable";
/** Format: uuid */
recording_id?: string;
score?: number;
}[];
/** @enum {string} */
state: "disabled" | "queued" | "searching" | "ready" | "not_found" | "needs_input" | "error";
input_hash: string;
candidates: components["schemas"]["ReleaseCandidate"][];
selected_release: string | null;
};
/** @description Пустые поля не меняют файлы. cover_base64 null снимает обложку пачки. */
UploadBatchPatch: {
artist?: string;
@@ -4651,6 +4781,132 @@ export interface operations {
default: components["responses"]["Problem"];
};
};
getUploadReleases: {
parameters: {
query?: {
group_id?: string;
};
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Состояние поиска и кандидаты; текущие файлы не изменяются */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadReleaseReport"];
};
};
default: components["responses"]["Problem"];
};
};
searchUploadReleases: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": {
artist?: string;
album?: string;
/** Format: uuid */
group_id?: string;
/** Format: uuid */
release_id?: string;
/** @description Явно распознать до 50 редактируемых треков через AcoustID; теги и аудио не отправляются. Требуется ключ приложения на сервере. */
audio?: boolean;
};
};
};
responses: {
/** @description Поиск поставлен в фоновую очередь */
202: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadReleaseReport"];
};
};
default: components["responses"]["Problem"];
};
};
getUploadReleaseCover: {
parameters: {
query?: {
group_id?: string;
};
header?: never;
path: {
id: components["parameters"]["EntityId"];
release_id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Ограниченное по размеру изображение; не меняет обложку пачки */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
image_base64: string;
mime_type: string;
source_url: string;
exact_release: boolean;
};
};
};
default: components["responses"]["Problem"];
};
};
applyUploadRelease: {
parameters: {
query?: never;
header?: never;
path: {
id: components["parameters"]["EntityId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/** Format: uuid */
group_id?: string;
/** Format: uuid */
release_id: string;
apply_metadata: boolean;
apply_cover: boolean;
};
};
};
responses: {
/** @description Применено к текущей пачке */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadReleaseReport"];
};
};
default: components["responses"]["Problem"];
};
};
reviewUploads: {
parameters: {
query?: never;