cr
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
* Transforms raw API data into database-ready formats
|
||||
*/
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import * as cheerio from "cheerio";
|
||||
import {
|
||||
RawKeyEvent,
|
||||
TransformedEvent,
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
GameStatsResponse,
|
||||
DbEventPayload,
|
||||
DbMarketPayload,
|
||||
} from './feeder.types';
|
||||
} from "./feeder.types";
|
||||
|
||||
@Injectable()
|
||||
export class FeederTransformerService {
|
||||
@@ -28,7 +28,7 @@ export class FeederTransformerService {
|
||||
// HELPER FUNCTIONS
|
||||
// ============================================
|
||||
private safeString(value: any): string | null {
|
||||
return value === null || value === undefined || value === ''
|
||||
return value === null || value === undefined || value === ""
|
||||
? null
|
||||
: String(value);
|
||||
}
|
||||
@@ -45,7 +45,7 @@ export class FeederTransformerService {
|
||||
|
||||
private extractPlayerIdFromUrl(url: string | undefined): string | null {
|
||||
if (!url) return null;
|
||||
const parts = url.split('/');
|
||||
const parts = url.split("/");
|
||||
return parts[parts.length - 1] || null;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export class FeederTransformerService {
|
||||
matchId: string,
|
||||
): TransformedEvent[] {
|
||||
return rawEvents.map((e) => {
|
||||
const playerId = this.extractPlayerIdFromUrl(e.playerUrl) || '';
|
||||
const playerId = this.extractPlayerIdFromUrl(e.playerUrl) || "";
|
||||
const assistPlayerId = e.assistPlayerUrl
|
||||
? this.extractPlayerIdFromUrl(e.assistPlayerUrl)
|
||||
: null;
|
||||
@@ -68,16 +68,16 @@ export class FeederTransformerService {
|
||||
: null;
|
||||
|
||||
// Determine event type
|
||||
let eventType: 'goal' | 'card' | 'substitute' | 'other' = 'other';
|
||||
if (e.type === 'goal') eventType = 'goal';
|
||||
else if (e.type === 'card') eventType = 'card';
|
||||
else if (e.type === 'substitute') eventType = 'substitute';
|
||||
let eventType: "goal" | "card" | "substitute" | "other" = "other";
|
||||
if (e.type === "goal") eventType = "goal";
|
||||
else if (e.type === "card") eventType = "card";
|
||||
else if (e.type === "substitute") eventType = "substitute";
|
||||
|
||||
return {
|
||||
matchId,
|
||||
playerId,
|
||||
playerName: e.playerName,
|
||||
teamId: e.position === 'home' ? homeTeamId : awayTeamId,
|
||||
teamId: e.position === "home" ? homeTeamId : awayTeamId,
|
||||
eventType,
|
||||
eventSubtype: e.subType || null,
|
||||
timeMinute: e.timeMin,
|
||||
@@ -136,7 +136,7 @@ export class FeederTransformerService {
|
||||
// GAME STATS TRANSFORMER
|
||||
// ============================================
|
||||
transformGameStats(
|
||||
data: GameStatsResponse['data'] | null,
|
||||
data: GameStatsResponse["data"] | null,
|
||||
): TransformedMatchStats | null {
|
||||
if (!data || !data.home) return null;
|
||||
|
||||
@@ -173,20 +173,20 @@ export class FeederTransformerService {
|
||||
// MATCH STATE TO STATUS MAPPER
|
||||
// ============================================
|
||||
mapMatchStateToStatus(state: MatchState | undefined): string {
|
||||
if (!state) return 'NS';
|
||||
if (!state) return "NS";
|
||||
|
||||
switch (state) {
|
||||
case 'postGame':
|
||||
case 'post':
|
||||
return 'FT';
|
||||
case 'preGame':
|
||||
case 'pre':
|
||||
return 'NS';
|
||||
case 'live':
|
||||
case 'liveGame':
|
||||
return 'LIVE';
|
||||
case "postGame":
|
||||
case "post":
|
||||
return "FT";
|
||||
case "preGame":
|
||||
case "pre":
|
||||
return "NS";
|
||||
case "live":
|
||||
case "liveGame":
|
||||
return "LIVE";
|
||||
default:
|
||||
return 'NS';
|
||||
return "NS";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,28 +200,28 @@ export class FeederTransformerService {
|
||||
const officials: MatchOfficial[] = [];
|
||||
|
||||
// Try standard officials component
|
||||
$('.p0c-match-officials__official-list-item').each((_, elem) => {
|
||||
$(".p0c-match-officials__official-list-item").each((_, elem) => {
|
||||
const name = $(elem)
|
||||
.find('.p0c-match-officials__official-name')
|
||||
.find(".p0c-match-officials__official-name")
|
||||
.text()
|
||||
.trim();
|
||||
const role = $(elem)
|
||||
.find('.p0c-match-officials__official-group-title')
|
||||
.find(".p0c-match-officials__official-group-title")
|
||||
.text()
|
||||
.trim();
|
||||
|
||||
if (name) {
|
||||
officials.push({ name, role: role || 'Referee' });
|
||||
officials.push({ name, role: role || "Referee" });
|
||||
}
|
||||
});
|
||||
|
||||
// Fallback: look for referee info in match info section
|
||||
if (officials.length === 0) {
|
||||
// Try alternative selectors
|
||||
$('.widget-match-info__referee-name, .referee-name').each((_, elem) => {
|
||||
$(".widget-match-info__referee-name, .referee-name").each((_, elem) => {
|
||||
const name = $(elem).text().trim();
|
||||
if (name) {
|
||||
officials.push({ name, role: 'Referee' });
|
||||
officials.push({ name, role: "Referee" });
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -331,8 +331,8 @@ export class FeederTransformerService {
|
||||
(
|
||||
e,
|
||||
): e is TransformedEvent & {
|
||||
eventType: 'goal' | 'card' | 'substitute';
|
||||
} => e.eventType !== 'other' && !!e.playerId,
|
||||
eventType: "goal" | "card" | "substitute";
|
||||
} => e.eventType !== "other" && !!e.playerId,
|
||||
)
|
||||
.map((e) => ({
|
||||
match_id: e.matchId,
|
||||
@@ -354,6 +354,6 @@ export class FeederTransformerService {
|
||||
// BASKETBALL PLAYER ID GENERATOR
|
||||
// ============================================
|
||||
generateBasketballPlayerId(teamId: string, playerName: string): string {
|
||||
return `${teamId}-${playerName.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase()}`;
|
||||
return `${teamId}-${playerName.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase()}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user