Socialify

Folder ..

Viewing FribbSyncTask.ts
104 lines (93 loc) • 3.7 KB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
import axios from 'axios';
import { Repository } from 'typeorm';
import { FribbMapping } from '../entities/FribbMapping';
import AppDataSource from '../database/data-source';
import Logger from '../utils/logger';

export interface FribbList {
    livechart_id: number;
    thetvdb_id: number;
    "anime-planet_id": string;
    imdb_id: string;
    anisearch_id: number;
    themoviedb_id: number;
    anidb_id: number;
    kitsu_id: number;
    mal_id: number;
    type: string;
    "notify.moe_id": string;
    anilist_id: number;
}

export class FribbSyncTask {
    private repository: Repository<FribbMapping>;
    private readonly FRIBB_URL = "https://raw.githubusercontent.com/Fribb/anime-lists/master/anime-list-full.json";

    constructor() {
        this.repository = AppDataSource.getRepository(FribbMapping);
    }

    async execute(): Promise<void> {
        try {
            Logger.info('Starting Fribb sync', { timestamp: true, prefix: 'FribbSync' });

            // Fetch the data
            const response = await axios.get<FribbList[]>(this.FRIBB_URL);
            const mappings = response.data;

            // Process in batches
            const batchSize = 100;
            for (let i = 0; i < mappings.length; i += batchSize) {
                const batch = mappings.slice(i, i + batchSize);
                await this.processBatch(batch);

                Logger.info(`Processed ${i + batch.length}/${mappings.length} mappings`, {
                    timestamp: true,
                    prefix: 'FribbSync'
                });
            }

            Logger.success('Fribb sync completed', { timestamp: true, prefix: 'FribbSync' });
        } catch (error) {
            Logger.error(`Fribb sync failed: ${error}`, { timestamp: true, prefix: 'FribbSync' });
            throw error;
        }
    }

    private async processBatch(mappings: FribbList[]): Promise<void> {
        for (const mapping of mappings) {
            try {
                // Create composite key for MAL and AniList IDs if both exist
                const mal_anilist_composite = mapping.mal_id && mapping.anilist_id
                    ? `${mapping.mal_id}-${mapping.anilist_id}`
                    : null;

                // Try to find existing mapping by livechart_id or mal_anilist_composite
                let entity = await this.repository.findOne({
                    where: [
                        { livechart_id: mapping.livechart_id },
                        ...(mal_anilist_composite
                            ? [{ mal_anilist_composite: mal_anilist_composite }]
                            : [])
                    ]
                });

                if (entity) {
                    // Update existing entity
                    Object.assign(entity, mapping, { mal_anilist_composite });
                    await this.repository.save(entity);
                } else {
                    // Create new entity
                    entity = this.repository.create({
                        ...mapping,
                        mal_anilist_composite: mal_anilist_composite || undefined
                    });
                    await this.repository.save(entity);
                }
            } catch (error) {
                Logger.error(`Error processing mapping: ${JSON.stringify(mapping)}: ${error}`, {
                    timestamp: true,
                    prefix: 'FribbSync'
                });
            }
        }
    }
}

// Initialize and export the task configuration
export const fribbSyncTask = {
    name: 'FribbSync',
    interval: 7 * 24 * 60 * 60 * 1000, // 1 week in milliseconds
    execute: async () => {
        const task = new FribbSyncTask();
        await task.execute();
    }
};