postiz/apps/workers/src/app/stars.controller.ts

81 lines
2.5 KiB
TypeScript

import { Controller } from '@nestjs/common';
import { EventPattern, Transport } from '@nestjs/microservices';
import { JSDOM } from 'jsdom';
import { StarsService } from '@gitroom/nestjs-libraries/database/prisma/stars/stars.service';
import { TrendingService } from '@gitroom/nestjs-libraries/services/trending.service';
import dayjs from 'dayjs';
@Controller()
export class StarsController {
constructor(
private _starsService: StarsService,
private _trendingService: TrendingService
) {}
@EventPattern('check_stars', Transport.REDIS)
async checkStars(data: { login: string }) {
// not to be affected by the limit, we scrape the HTML instead of using the API
const loadedHtml = await (
await fetch(`https://github.com/${data.login}`)
).text();
const dom = new JSDOM(loadedHtml);
const totalStars =
+dom.window.document
.querySelector('#repo-stars-counter-star')
?.getAttribute('title')
?.replace(/,/g, '') || 0;
const totalForks = +dom.window.document
.querySelector('#repo-network-counter')
?.getAttribute('title')
?.replace(/,/g, '');
const lastValue = await this._starsService.getLastStarsByLogin(data.login);
if (
dayjs(lastValue.date).format('YYYY-MM-DD') ===
dayjs().format('YYYY-MM-DD')
) {
console.log('stars already synced for today');
return;
}
const totalNewsStars = totalStars - (lastValue?.totalStars || 0);
const totalNewsForks = totalForks - (lastValue?.totalForks || 0);
// if there is no stars in the database, we need to sync the stars
if (!lastValue?.totalStars) {
return;
}
// if there is stars in the database, sync the new stars
return this._starsService.createStars(
data.login,
totalNewsStars,
totalStars,
totalNewsForks,
totalForks,
new Date()
);
}
@EventPattern('sync_all_stars', Transport.REDIS, { concurrency: 1 })
async syncAllStars(data: { login: string }) {
// if there is a sync in progress, it's better not to touch it
if (
data?.login &&
(await this._starsService.getStarsByLogin(data?.login)).length
) {
return;
}
const findValidToken = await this._starsService.findValidToken(data?.login);
await this._starsService.sync(data.login, findValidToken?.token);
}
@EventPattern('sync_trending', Transport.REDIS, { concurrency: 1 })
async syncTrending() {
return this._trendingService.syncTrending();
}
}