fix(sites): integrate shared download access and register synced adapters
This commit is contained in:
1 parent
6dab134617
commit
36f3ece5b5
20 files changed
+175
-38
No files matched your search
@@ -9,12 +9,10 @@ import {
|
||||
fetchEpisodeGroup,
|
||||
fetchRichDetail,
|
||||
fetchRichSeason,
|
||||
getSiteAdapter,
|
||||
getSiteDefinition,
|
||||
groupSeasonAsRichSeason,
|
||||
type ProbeResult,
|
||||
qbAuthConfig,
|
||||
type SecretResolver,
|
||||
SiteError,
|
||||
type TmdbRichDetail,
|
||||
type TmdbRichSeasonDetail,
|
||||
@@ -200,20 +198,8 @@ export function createPorts(
|
||||
const siteMeta = (raw._site ?? {}) as Record<string, unknown>;
|
||||
const defId = [str(siteMeta.adapterSiteId), site.key].find((k) => k && getSiteDefinition(k));
|
||||
if (!defId) throw new SiteError(site.id, "unsupported", `站点 ${site.key} 没有可用的适配器定义`);
|
||||
const accounts = await ctx.db
|
||||
.selectFrom("site_account")
|
||||
.select(["auth_kind", "secret_ref"])
|
||||
.where("site_id", "=", site.id)
|
||||
.where("enabled", "=", true)
|
||||
.execute();
|
||||
const secrets: SecretResolver = {
|
||||
async resolve({ kind }) {
|
||||
const want = kind === "apiKey" ? "api_key" : kind;
|
||||
const acc = accounts.find((a) => a.auth_kind === want);
|
||||
return (await resolveSecret(acc?.secret_ref ?? null)) ?? null;
|
||||
},
|
||||
};
|
||||
const adapter = getSiteAdapter(defId, { secrets, baseUrl: site.base_url });
|
||||
// 与搜索/详情共用站点出口、账号会话、UA 和跨进程限流;API 基址仍取站点配置。
|
||||
const adapter = rt().siteAdapter({ ...site, key: defId });
|
||||
const t = await adapter.downloadTarget(release.site_release_id);
|
||||
if (t.kind === "torrent")
|
||||
return { kind: "file", bytes: t.bytes, ...(t.fileName ? { filename: t.fileName } : {}) };
|
||||
|
||||
@@ -199,6 +199,13 @@ export class SourcesRuntime {
|
||||
const pick = typeof ua === "function" ? ua() : ua !== undefined ? Promise.resolve(ua) : this.defaultUserAgent();
|
||||
headers.set("user-agent", await pick);
|
||||
}
|
||||
const credentials = init?.credentials ?? (input instanceof Request ? input.credentials : undefined);
|
||||
if (credentials === "omit") {
|
||||
// 签名下载不复用账号 Cookie 或浏览器 profile,包括 cf_clearance。
|
||||
headers.delete("cookie");
|
||||
headers.delete("authorization");
|
||||
return base(input, { ...init, headers, credentials });
|
||||
}
|
||||
if (!siteId) return base(input, { ...init, headers });
|
||||
const url = input instanceof Request ? input.url : String(input);
|
||||
const method = init?.method ?? (input instanceof Request ? input.method : "GET");
|
||||
|
||||
@@ -413,10 +413,11 @@ export async function refreshSiteAccount(
|
||||
const profile = (def.umt as { profile?: Record<string, string> }).profile;
|
||||
const vipLevels = (def.umt as { vipLevels?: string[] }).vipLevels;
|
||||
// 馒头 API 基址与适配器一致:站点配置 > 定义里的 apiBaseUrl;不再由站点地址推 api.<根域>(IP / 本地地址会拼成非法 URL)
|
||||
const siteConfig = (site.config ?? {}) as { apiBaseUrl?: string; userdataPath?: string };
|
||||
const apiUrl =
|
||||
def.umt.kind === "mteam"
|
||||
? (site.config as { apiBaseUrl?: string })?.apiBaseUrl || mteamApiBase(def as MteamDefinition)
|
||||
: null;
|
||||
? siteConfig.apiBaseUrl || mteamApiBase(def as MteamDefinition)
|
||||
: siteConfig.apiBaseUrl || ("api_url" in def ? def.api_url : null);
|
||||
|
||||
const fetchUserData = async (
|
||||
cred: { cookie?: string | null; apikey?: string | null },
|
||||
@@ -425,6 +426,7 @@ export async function refreshSiteAccount(
|
||||
const info = await refreshSiteUserData({
|
||||
name: site.name,
|
||||
url: site.base_url,
|
||||
...(siteConfig.userdataPath ? { userdataPath: siteConfig.userdataPath } : {}),
|
||||
schema: (def as { schema?: string }).schema ?? null,
|
||||
public: true,
|
||||
cookie: cred.cookie ?? null,
|
||||
|
||||
Reference in new issue
Block a user