refactor: refactor collection
This commit is contained in:
@@ -41,7 +41,7 @@ describe('DownloadService', () => {
|
||||
|
||||
it('should call BilibiliDownloader.downloadSinglePart', async () => {
|
||||
await downloadService.downloadSingleBilibiliPart('url', 1, 2, 'title');
|
||||
expect(BilibiliDownloader.downloadSinglePart).toHaveBeenCalledWith('url', 1, 2, 'title', undefined, undefined);
|
||||
expect(BilibiliDownloader.downloadSinglePart).toHaveBeenCalledWith('url', 1, 2, 'title', undefined, undefined, undefined);
|
||||
});
|
||||
|
||||
it('should call BilibiliDownloader.downloadCollection', async () => {
|
||||
|
||||
@@ -43,4 +43,3 @@ export const deleteCookies = async (
|
||||
cookieService.deleteCookies();
|
||||
res.json(successMessage("Cookies deleted successfully"));
|
||||
};
|
||||
|
||||
|
||||
@@ -359,6 +359,15 @@ export const downloadVideo = async (
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Get collection name if collectionId is provided
|
||||
let collectionName: string | undefined;
|
||||
if (collectionId) {
|
||||
const collection = storageService.getCollectionById(collectionId);
|
||||
if (collection) {
|
||||
collectionName = collection.name || collection.title;
|
||||
}
|
||||
}
|
||||
|
||||
// Download the first part
|
||||
firstPartResult =
|
||||
await downloadService.downloadSingleBilibiliPart(
|
||||
@@ -367,7 +376,8 @@ export const downloadVideo = async (
|
||||
videosNumber,
|
||||
title || "Bilibili Video",
|
||||
downloadId,
|
||||
registerCancel
|
||||
registerCancel,
|
||||
collectionName
|
||||
);
|
||||
|
||||
// Add to collection if needed
|
||||
|
||||
@@ -131,7 +131,8 @@ export async function downloadSingleBilibiliPart(
|
||||
totalParts: number,
|
||||
seriesTitle: string,
|
||||
downloadId?: string,
|
||||
onStart?: (cancel: () => void) => void
|
||||
onStart?: (cancel: () => void) => void,
|
||||
collectionName?: string
|
||||
): Promise<DownloadResult> {
|
||||
return BilibiliDownloader.downloadSinglePart(
|
||||
url,
|
||||
@@ -139,7 +140,8 @@ export async function downloadSingleBilibiliPart(
|
||||
totalParts,
|
||||
seriesTitle,
|
||||
downloadId,
|
||||
onStart
|
||||
onStart,
|
||||
collectionName
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,8 @@ export class BilibiliDownloader extends BaseDownloader {
|
||||
totalParts: number,
|
||||
seriesTitle: string,
|
||||
downloadId?: string,
|
||||
onStart?: (cancel: () => void) => void
|
||||
onStart?: (cancel: () => void) => void,
|
||||
collectionName?: string
|
||||
): Promise<DownloadResult> {
|
||||
return bilibiliVideo.downloadSinglePart(
|
||||
url,
|
||||
@@ -135,7 +136,8 @@ export class BilibiliDownloader extends BaseDownloader {
|
||||
totalParts,
|
||||
seriesTitle,
|
||||
downloadId,
|
||||
onStart
|
||||
onStart,
|
||||
collectionName
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +224,9 @@ export async function downloadCollection(
|
||||
videoNumber,
|
||||
videos.length,
|
||||
title || "Collection",
|
||||
downloadId
|
||||
downloadId,
|
||||
undefined, // onStart
|
||||
mytubeCollection.name || mytubeCollection.title // collectionName
|
||||
);
|
||||
|
||||
// If download was successful, add to collection
|
||||
@@ -360,13 +362,24 @@ export async function downloadRemainingParts(
|
||||
);
|
||||
}
|
||||
|
||||
// Get collection name if collectionId is provided
|
||||
let collectionName: string | undefined;
|
||||
if (collectionId) {
|
||||
const collection = storageService.getCollectionById(collectionId);
|
||||
if (collection) {
|
||||
collectionName = collection.name || collection.title;
|
||||
}
|
||||
}
|
||||
|
||||
// Download this part
|
||||
const result = await downloadSinglePart(
|
||||
partUrl,
|
||||
part,
|
||||
totalParts,
|
||||
seriesTitle,
|
||||
downloadId
|
||||
downloadId,
|
||||
undefined, // onStart
|
||||
collectionName
|
||||
);
|
||||
|
||||
if (result.success && result.videoData) {
|
||||
|
||||
@@ -12,7 +12,8 @@ import { getCookieHeader } from "./bilibiliCookie";
|
||||
*/
|
||||
export async function downloadSubtitles(
|
||||
videoUrl: string,
|
||||
baseFilename: string
|
||||
baseFilename: string,
|
||||
collectionName?: string
|
||||
): Promise<Array<{ language: string; filename: string; path: string }>> {
|
||||
try {
|
||||
const videoId = extractBilibiliVideoId(videoUrl);
|
||||
@@ -94,8 +95,16 @@ export async function downloadSubtitles(
|
||||
|
||||
const savedSubtitles = [];
|
||||
|
||||
// Determine subtitle directory based on collection name
|
||||
const subtitleDir = collectionName
|
||||
? path.join(SUBTITLES_DIR, collectionName)
|
||||
: SUBTITLES_DIR;
|
||||
const subtitlePathPrefix = collectionName
|
||||
? `/subtitles/${collectionName}`
|
||||
: `/subtitles`;
|
||||
|
||||
// Ensure subtitles directory exists
|
||||
fs.ensureDirSync(SUBTITLES_DIR);
|
||||
fs.ensureDirSync(subtitleDir);
|
||||
|
||||
// Process subtitles (matching v1.5.14 approach - simple and direct)
|
||||
for (const sub of subtitlesData) {
|
||||
@@ -127,7 +136,7 @@ export async function downloadSubtitles(
|
||||
|
||||
if (vttContent) {
|
||||
const subFilename = `${baseFilename}.${lang}.vtt`;
|
||||
const subPath = path.join(SUBTITLES_DIR, subFilename);
|
||||
const subPath = path.join(subtitleDir, subFilename);
|
||||
|
||||
fs.writeFileSync(subPath, vttContent);
|
||||
logger.info(`Saved subtitle file: ${subPath}`);
|
||||
@@ -135,7 +144,7 @@ export async function downloadSubtitles(
|
||||
savedSubtitles.push({
|
||||
language: lang,
|
||||
filename: subFilename,
|
||||
path: `/subtitles/${subFilename}`,
|
||||
path: `${subtitlePathPrefix}/${subFilename}`,
|
||||
});
|
||||
} else {
|
||||
logger.warn(`Failed to convert subtitle to VTT format for ${lang}`);
|
||||
|
||||
@@ -376,7 +376,8 @@ export async function downloadSinglePart(
|
||||
totalParts: number,
|
||||
seriesTitle: string,
|
||||
downloadId?: string,
|
||||
onStart?: (cancel: () => void) => void
|
||||
onStart?: (cancel: () => void) => void,
|
||||
collectionName?: string
|
||||
): Promise<DownloadResult> {
|
||||
try {
|
||||
logger.info(
|
||||
@@ -395,9 +396,21 @@ export async function downloadSinglePart(
|
||||
const videoFilename = `${safeBaseFilename}.${mergeOutputFormat}`;
|
||||
const thumbnailFilename = `${safeBaseFilename}.jpg`;
|
||||
|
||||
// Determine directories based on collection name
|
||||
const videoDir = collectionName
|
||||
? path.join(VIDEOS_DIR, collectionName)
|
||||
: VIDEOS_DIR;
|
||||
const imageDir = collectionName
|
||||
? path.join(IMAGES_DIR, collectionName)
|
||||
: IMAGES_DIR;
|
||||
|
||||
// Ensure directories exist
|
||||
fs.ensureDirSync(videoDir);
|
||||
fs.ensureDirSync(imageDir);
|
||||
|
||||
// Set full paths for video and thumbnail
|
||||
const videoPath = path.join(VIDEOS_DIR, videoFilename);
|
||||
const thumbnailPath = path.join(IMAGES_DIR, thumbnailFilename);
|
||||
const videoPath = path.join(videoDir, videoFilename);
|
||||
const thumbnailPath = path.join(imageDir, thumbnailFilename);
|
||||
|
||||
let videoTitle,
|
||||
videoAuthor,
|
||||
@@ -528,9 +541,9 @@ export async function downloadSinglePart(
|
||||
const newVideoFilename = `${newSafeBaseFilename}.${mergeOutputFormat}`;
|
||||
const newThumbnailFilename = `${newSafeBaseFilename}.jpg`;
|
||||
|
||||
// Rename the files
|
||||
const newVideoPath = path.join(VIDEOS_DIR, newVideoFilename);
|
||||
const newThumbnailPath = path.join(IMAGES_DIR, newThumbnailFilename);
|
||||
// Rename the files (use same directories as before)
|
||||
const newVideoPath = path.join(videoDir, newVideoFilename);
|
||||
const newThumbnailPath = path.join(imageDir, newThumbnailFilename);
|
||||
|
||||
// Check if download was cancelled before processing files
|
||||
const downloader = new BilibiliDownloaderHelper();
|
||||
@@ -601,7 +614,11 @@ export async function downloadSinglePart(
|
||||
}> = [];
|
||||
try {
|
||||
logger.info("Attempting to download subtitles...");
|
||||
subtitles = await downloadSubtitles(url, newSafeBaseFilename);
|
||||
subtitles = await downloadSubtitles(
|
||||
url,
|
||||
newSafeBaseFilename,
|
||||
collectionName
|
||||
);
|
||||
logger.info(`Downloaded ${subtitles.length} subtitles`);
|
||||
} catch (e) {
|
||||
// If it's a cancellation error, re-throw it
|
||||
@@ -646,9 +663,13 @@ export async function downloadSinglePart(
|
||||
thumbnailFilename: thumbnailSaved ? finalThumbnailFilename : undefined,
|
||||
subtitles: subtitles.length > 0 ? subtitles : undefined,
|
||||
thumbnailUrl: thumbnailUrl || undefined,
|
||||
videoPath: `/videos/${finalVideoFilename}`,
|
||||
videoPath: collectionName
|
||||
? `/videos/${collectionName}/${finalVideoFilename}`
|
||||
: `/videos/${finalVideoFilename}`,
|
||||
thumbnailPath: thumbnailSaved
|
||||
? `/images/${finalThumbnailFilename}`
|
||||
? collectionName
|
||||
? `/images/${collectionName}/${finalThumbnailFilename}`
|
||||
: `/images/${finalThumbnailFilename}`
|
||||
: null,
|
||||
duration: duration,
|
||||
fileSize: fileSize,
|
||||
@@ -679,12 +700,16 @@ export async function downloadSinglePart(
|
||||
const updatedVideo = storageService.updateVideo(existingVideo.id, {
|
||||
subtitles: subtitles.length > 0 ? subtitles : undefined,
|
||||
videoFilename: finalVideoFilename,
|
||||
videoPath: `/videos/${finalVideoFilename}`,
|
||||
videoPath: collectionName
|
||||
? `/videos/${collectionName}/${finalVideoFilename}`
|
||||
: `/videos/${finalVideoFilename}`,
|
||||
thumbnailFilename: thumbnailSaved
|
||||
? finalThumbnailFilename
|
||||
: existingVideo.thumbnailFilename,
|
||||
thumbnailPath: thumbnailSaved
|
||||
? `/images/${finalThumbnailFilename}`
|
||||
? collectionName
|
||||
? `/images/${collectionName}/${finalThumbnailFilename}`
|
||||
: `/images/${finalThumbnailFilename}`
|
||||
: existingVideo.thumbnailPath,
|
||||
duration: duration,
|
||||
fileSize: fileSize,
|
||||
|
||||
Reference in New Issue
Block a user