Skip to content

Commit

Permalink
feat: extract bilibili logic
Browse files Browse the repository at this point in the history
  • Loading branch information
JimmyLv committed Mar 3, 2023
1 parent a4c5cfa commit a54223c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 79 deletions.
122 changes: 44 additions & 78 deletions pages/api/summarize.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Redis } from "@upstash/redis";
import type { NextFetchEvent, NextRequest } from "next/server";
import { NextResponse } from "next/server";
import pRetry from "p-retry";
import { fetchSubtitle } from "../../utils/3rd/bilibili";
import { isDev } from "../../utils/env";
import { OpenAIResult } from "../../utils/OpenAIResult";
import { getChunckedTranscripts, getSummaryPrompt } from "../../utils/prompt";
Expand All @@ -14,21 +14,6 @@ if (!process.env.OPENAI_API_KEY) {
throw new Error("Missing env var from OpenAI");
}

const run = async (bvId: string) => {
const requestUrl = `https://api.bilibili.com/x/web-interface/view?bvid=${bvId}`;
console.log(`fetch`, requestUrl);
const response = await fetch(requestUrl, {
method: "GET",
});
const json = await response.json();
const subtitleList = json.data?.subtitle?.list;
if (!subtitleList || subtitleList?.length < 1) {
throw new Error('no subtitle');
}

return json;
};

export default async function handler(
req: NextRequest,
context: NextFetchEvent
Expand All @@ -41,72 +26,53 @@ export default async function handler(
if (!bvId) {
return new Response("No bvid in the request", { status: 500 });
}
let res
try {
res = await pRetry(() => run(bvId), {
onFailedAttempt: (error) => {
console.log(
`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`
);
},
retries: 3,
const { title, subtitles } = await fetchSubtitle(bvId);
if (!subtitles) {
console.error("No subtitle in the video: ", bvId);
return new Response("No subtitle in the video", { status: 501 });
}
// @ts-ignore
const transcripts = subtitles.body.map((item, index) => {
return {
text: `${item.from}: ${item.content}`,
index,
};
});
} catch (e) {
return new Response("No subtitle in the video", { status: 501 });
}
// @ts-ignore
const title = res.data?.title;
const subtitleList = res.data?.subtitle?.list;
if (!subtitleList || subtitleList?.length < 1) {
console.error("No subtitle in the video: ", bvId);
return new Response("No subtitle in the video", { status: 501 });
}
const betterSubtitle =
subtitleList.find(({ lan }: { lan: string }) => lan === "zh-CN") ||
subtitleList[0];
const subtitleUrl = betterSubtitle?.subtitle_url;
console.log("subtitle_url", subtitleUrl);
// console.log("========transcripts========", transcripts);
const text = getChunckedTranscripts(transcripts, transcripts);
const prompt = getSummaryPrompt(title, text, true);

const subtitleResponse = await fetch(subtitleUrl);
const subtitles = await subtitleResponse.json();
// @ts-ignore
const transcripts = subtitles.body.map((item, index) => {
return {
text: `${item.from}: ${item.content}`,
index,
};
});
// console.log("========transcripts========", transcripts);
const text = getChunckedTranscripts(transcripts, transcripts);
const prompt = getSummaryPrompt(title, text, true);

try {
apiKey && console.log("========use user apiKey========");
isDev && console.log("prompt", prompt);
const payload = {
model: "gpt-3.5-turbo",
messages: [{ role: "user" as const, content: prompt }],
temperature: 0.5,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
max_tokens: apiKey ? 400 : 300,
stream: false,
n: 1,
};
try {
apiKey && console.log("========use user apiKey========");
isDev && console.log("prompt", prompt);
const payload = {
model: "gpt-3.5-turbo",
messages: [{ role: "user" as const, content: prompt }],
temperature: 0.5,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
max_tokens: apiKey ? 400 : 300,
stream: false,
n: 1,
};

const result = await OpenAIResult(payload, apiKey);
// TODO: add better logging when dev or prod
console.log("result", result);
const redis = Redis.fromEnv();
const data = await redis.set(bvId, result);
console.log(`bvId ${bvId} cached:`, data);
const result = await OpenAIResult(payload, apiKey);
// TODO: add better logging when dev or prod
console.log("result", result);
const redis = Redis.fromEnv();
const data = await redis.set(bvId, result);
console.log(`bvId ${bvId} cached:`, data);

return NextResponse.json(result);
} catch (error: any) {
console.log('API error', error, error.message);
return NextResponse.json({
errorMessage: error.message,
});
return NextResponse.json(result);
} catch (error: any) {
console.log("API error", error, error.message);
return NextResponse.json({
errorMessage: error.message,
});
}
} catch (e) {
return new Response("No subtitle in the video", { status: 501 });
}
}
43 changes: 43 additions & 0 deletions utils/3rd/bilibili.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pRetry from "p-retry";

const run = async (bvId: string) => {
const requestUrl = `https://api.bilibili.com/x/web-interface/view?bvid=${bvId}`;
console.log(`fetch`, requestUrl);
const response = await fetch(requestUrl, {
method: "GET",
});
const json = await response.json();
const subtitleList = json.data?.subtitle?.list;
if (!subtitleList || subtitleList?.length < 1) {
throw new Error("no subtitle");
}

return json;
};

export async function fetchSubtitle(bvId: string) {
const res = await pRetry(() => run(bvId), {
onFailedAttempt: (error) => {
console.log(
`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`
);
},
retries: 3,
});
// @ts-ignore
const title = res.data?.title;
const subtitleList = res.data?.subtitle?.list;
if (!subtitleList || subtitleList?.length < 1) {
return { title, subtitles: null };
}

const betterSubtitle =
subtitleList.find(({ lan }: { lan: string }) => lan === "zh-CN") ||
subtitleList[0];
const subtitleUrl = betterSubtitle?.subtitle_url;
console.log("subtitle_url", subtitleUrl);

const subtitleResponse = await fetch(subtitleUrl);
const subtitles = await subtitleResponse.json();
return { title, subtitles };
}
5 changes: 4 additions & 1 deletion utils/3rd/lemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export async function checkLicenseKey(licenseKey: string) {
},
});
const keysData = await response.json();
const licenseKeys = keysData.data?.map((i: any) => i.attributes.key);
const licenseKeys = keysData.data?.map((i: any) => {
console.log("========i.attributes========", i.attributes);
return i.attributes.key;
});

if (licenseKeys?.includes(licenseKey.toLowerCase())) {
// TODO: change to supabase after implement user-login
Expand Down

0 comments on commit a54223c

Please sign in to comment.