import PocketBase from 'pocketbase'; import fs from 'fs'; import path from 'path'; const LOCAL_URL = 'http://127.0.0.1:8090'; const SERVER_URL = 'https://avt-back.ru/'; const ADMIN_EMAIL = 'redibedi2019@gmail.com'; const ADMIN_PASSWORD = 'Stalin4444'; const LOCAL_STORAGE_DIR = 'D:/Verstka/production/astro_avtourist/backend/pb_data/storage/pbc_1125843985'; interface Post { id: string; title: string; slug: string; description: string; content: string; author: string; category: string; categoryColor: string; date: string; readTime: string; readmeTime: string; image: string; draft: boolean; views: number; created: string; updated: string; } async function main() { console.log('🔄 Синхронизация постов: Локальный → Публичный сервер\n'); // Подключение к локальному PocketBase const localPb = new PocketBase(LOCAL_URL); await localPb.admins.authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD); console.log('✅ Подключено к локальной БД'); // Подключение к публичному серверу const serverPb = new PocketBase(SERVER_URL); await serverPb.admins.authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD); console.log('✅ Подключено к публичному серверу\n'); // Получение постов с локальной БД console.log('📥 Получение постов с локальной БД...'); const localPosts = await localPb.collection('posts').getFullList({ filter: 'slug != "" && title != ""', }); // Фильтруем только неп черновые посты const publishedPosts = localPosts.filter(p => !p.draft && p.slug); console.log(`📊 Локально: ${publishedPosts.length} опубликованных постов\n`); // Получение постов с публичного сервера console.log('📥 Получение постов с публичного сервера...'); const serverPosts = await serverPb.collection('posts').getFullList(); const serverSlugs = new Set(serverPosts.map(p => p.slug)); console.log(`📊 На сервере: ${serverPosts.length} постов\n`); // Синхронизация постов let created = 0; let skipped = 0; let imagesUploaded = 0; for (const post of publishedPosts) { // Проверяем, существует ли пост на сервере if (serverSlugs.has(post.slug)) { console.log(`⏭️ Пропущен (уже есть): ${post.slug}`); skipped++; continue; } console.log(`📝 Создаю пост: ${post.slug}`); try { // Если есть картинка - загружаем через FormData if (post.image) { const imagePath = path.join(LOCAL_STORAGE_DIR, post.id, post.image); if (fs.existsSync(imagePath)) { console.log(` 📷 Загружаю изображение: ${post.image}`); const formData = new FormData(); const fileBuffer = fs.readFileSync(imagePath); const blob = new Blob([fileBuffer]); const file = new File([blob], post.image); formData.append('image', file); formData.append('title', post.title); formData.append('slug', post.slug); formData.append('description', post.description || ''); formData.append('content', post.content || ''); formData.append('author', post.author || ''); formData.append('category', post.category || ''); formData.append('categoryColor', post.categoryColor || ''); formData.append('date', post.date || ''); formData.append('readTime', post.readTime || ''); formData.append('readmeTime', post.readTime || post.readmeTime || ''); formData.append('draft', String(post.draft ?? false)); formData.append('views', String(post.views ?? 0)); await serverPb.collection('posts').create(formData); console.log(` ✅ Создан с картинкой`); imagesUploaded++; } else { // Файла нет - создаем без картинки console.log(` ⚠️ Картинка не найдена: ${imagePath}`); await serverPb.collection('posts').create({ title: post.title, slug: post.slug, description: post.description || '', content: post.content || '', author: post.author || '', category: post.category || '', categoryColor: post.categoryColor || '', date: post.date || '', readTime: post.readTime || '', readmeTime: post.readTime || post.readmeTime || '', image: '', draft: post.draft ?? false, views: post.views ?? 0, }); console.log(` ✅ Создан без картинки`); } } else { // Нет картинки - создаем без неё await serverPb.collection('posts').create({ title: post.title, slug: post.slug, description: post.description || '', content: post.content || '', author: post.author || '', category: post.category || '', categoryColor: post.categoryColor || '', date: post.date || '', readTime: post.readTime || post.readmeTime || '', image: '', draft: post.draft ?? false, views: post.views ?? 0, }); console.log(` ✅ Создан без картинки`); } created++; } catch (e: any) { console.error(` ❌ Ошибка:`, e.response?.data || e.message); } } console.log('\n📊 Итоги:'); console.log(` ✅ Создано: ${created}`); console.log(` ⏭️ Пропущено: ${skipped}`); console.log(` 🖼️ Картинок загружено: ${imagesUploaded}`); } main().catch(console.error);