astro_avtourist/scripts/sync-posts.ts

158 lines
No EOL
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Post>({
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<Post>();
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);