81 lines
2.5 KiB
TypeScript
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();
|
|
}
|
|
}
|