refactor: Update runMigrations to be an async function

This commit is contained in:
Peifan Li
2025-12-03 23:34:47 -05:00
parent f4dbccc978
commit e2d4559def
5 changed files with 71 additions and 31 deletions

View File

@@ -2,6 +2,8 @@
一个 YouTube/Bilibili/MissAV 视频下载和播放应用,支持频道订阅与自动下载,允许您将视频及其缩略图本地保存。将您的视频整理到收藏夹中,以便轻松访问和管理。现已支持[yt-dlp所有网址](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md##)包括微博小红书x.com等。
[![Discord](https://img.shields.io/badge/Discord-Join_Us-7289DA?logo=discord&logoColor=white)](https://discord.gg/tqucdh7a)
[English](README.md)
## 在线演示

View File

@@ -1,7 +1,11 @@
# MyTube
[![Discord](https://img.shields.io/badge/Discord-Join_Us-7289DA?logo=discord&logoColor=white)](https://discord.gg/tqucdh7a)
A YouTube/Bilibili/MissAV video downloader and player that supports channel subscriptions and auto-downloads, allowing you to save videos and thumbnails locally. Organize your videos into collections for easy access and management. Now supports [yt-dlp sites](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md##), including Weibo, Xiaohongshu, X.com, etc.
[![Discord](https://img.shields.io/badge/Discord-Join_Us-7289DA?logo=discord&logoColor=white)](https://discord.gg/tqucdh7a)
[中文](README-zh.md)
## Demo

View File

@@ -3,7 +3,7 @@ import path from 'path';
import { ROOT_DIR } from '../config/paths';
import { db } from './index';
export function runMigrations() {
export async function runMigrations() {
try {
console.log('Running database migrations...');
// In production/docker, the drizzle folder is copied to the root or src/drizzle
@@ -14,6 +14,28 @@ export function runMigrations() {
migrate(db, { migrationsFolder });
console.log('Database migrations completed successfully.');
// Check for legacy data files and run data migration if found
const { runMigration: runDataMigration } = await import('../services/migrationService');
const { VIDEOS_DATA_PATH, COLLECTIONS_DATA_PATH, STATUS_DATA_PATH } = await import('../config/paths');
const fs = await import('fs-extra');
// Hardcoded path for settings as in migrationService
const SETTINGS_DATA_PATH = path.join(path.dirname(VIDEOS_DATA_PATH), 'settings.json');
const hasLegacyData =
fs.existsSync(VIDEOS_DATA_PATH) ||
fs.existsSync(COLLECTIONS_DATA_PATH) ||
fs.existsSync(STATUS_DATA_PATH) ||
fs.existsSync(SETTINGS_DATA_PATH);
if (hasLegacyData) {
console.log('Legacy data files found. Running data migration...');
await runDataMigration();
} else {
console.log('No legacy data files found. Skipping data migration.');
}
} catch (error) {
console.error('Error running database migrations:', error);
// Don't throw, as we might want the app to start even if migration fails (though it might be broken)

View File

@@ -5,6 +5,7 @@ dotenv.config();
import cors from "cors";
import express from "express";
import { IMAGES_DIR, SUBTITLES_DIR, VIDEOS_DIR } from "./config/paths";
import { runMigrations } from "./db/migrate";
import apiRoutes from "./routes/api";
import settingsRoutes from './routes/settingsRoutes';
import downloadManager from "./services/downloadManager";
@@ -23,36 +24,47 @@ app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Initialize storage (create directories, etc.)
storageService.initializeStorage();
// Run database migrations
import { runMigrations } from "./db/migrate";
runMigrations();
// Initialize download manager (restore queued tasks)
downloadManager.initialize();
// Serve static files
app.use("/videos", express.static(VIDEOS_DIR));
app.use("/images", express.static(IMAGES_DIR));
app.use("/subtitles", express.static(SUBTITLES_DIR));
// API Routes
app.use("/api", apiRoutes);
app.use('/api/settings', settingsRoutes);
// storageService.initializeStorage(); // Moved inside startServer
// Start the server
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
// Start subscription scheduler
import("./services/subscriptionService").then(({ subscriptionService }) => {
subscriptionService.startScheduler();
}).catch(err => console.error("Failed to start subscription service:", err));
const startServer = async () => {
try {
// Run database migrations
await runMigrations();
// Run duration backfill in background
import("./services/metadataService").then(service => {
service.backfillDurations();
}).catch(err => console.error("Failed to start metadata service:", err));
});
// Initialize storage (create directories, etc.)
storageService.initializeStorage();
// Initialize download manager (restore queued tasks)
downloadManager.initialize();
// Serve static files
app.use("/videos", express.static(VIDEOS_DIR));
app.use("/images", express.static(IMAGES_DIR));
app.use("/subtitles", express.static(SUBTITLES_DIR));
// API Routes
app.use("/api", apiRoutes);
app.use('/api/settings', settingsRoutes);
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
// Start subscription scheduler
import("./services/subscriptionService").then(({ subscriptionService }) => {
subscriptionService.startScheduler();
}).catch(err => console.error("Failed to start subscription service:", err));
// Run duration backfill in background
import("./services/metadataService").then(service => {
service.backfillDurations();
}).catch(err => console.error("Failed to start metadata service:", err));
});
} catch (error) {
console.error("Failed to start server:", error);
process.exit(1);
}
};
startServer();

View File

@@ -25,7 +25,6 @@ class DownloadManager {
this.activeTasks = new Map();
this.activeDownloads = 0;
this.maxConcurrentDownloads = 3; // Default
this.loadSettings();
}
private async loadSettings() {
@@ -46,6 +45,7 @@ class DownloadManager {
initialize(): void {
try {
console.log("Initializing DownloadManager...");
this.loadSettings();
const status = storageService.getDownloadStatus();
const queuedDownloads = status.queuedDownloads;