Skip to content

Commit

Permalink
Store betika games in DB
Browse files Browse the repository at this point in the history
  • Loading branch information
nigelnindodev committed Oct 18, 2023
1 parent 3abd821 commit c06c4f2
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 33 deletions.
62 changes: 59 additions & 3 deletions src/core/game_events/betika/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import { BaseGameEventsProcessor } from "..";
import { getConfig } from "../../..";
import { BetProvider } from "../../../bet_providers";
import { BetikaProvider } from "../../../bet_providers/betika";
import { PostgresDataSourceSingleton } from "../../../datastores/postgres";
import { insertThreeWayGameEvent } from "../../../datastores/postgres/queries/three_way_game_event";
import { insertTwoWayGameEvent } from "../../../datastores/postgres/queries/two_way_game_event";
import { RedisSingleton } from "../../../datastores/redis";
import { getRedisProcessedEventsChannelName } from "../../../utils/redis";
import { ProcessedGameEvents } from "../../../utils/types/common";
import { BetTypes, ProcessedGameEvents } from "../../../utils/types/common";
import { DbThreeWayGameEvent, DbTwoWayGameEvent } from "../../../utils/types/db";
import { Result } from "../../../utils/types/result_type";

const {logger} = getConfig();
Expand All @@ -24,13 +28,65 @@ export class BetikaGameEventsProcessor extends BaseGameEventsProcessor {
return getBetProviderConfigResult;
}

const getPostgresDbResult = await PostgresDataSourceSingleton.getInstance(getConfig());
if (getPostgresDbResult.result === "error") {
logger.error(`Events processor failed to get postgres connection for provider ${this.betProvider.name} with error: `,getPostgresDbResult.value.message);
return getPostgresDbResult;
}

const getRedisSubscriberResult = await RedisSingleton.getSubscriber();
if (getRedisSubscriberResult.result === "success") {
const betProviderConfig = getBetProviderConfigResult.value;
const results = betProviderConfig.games.map(async game => {
await getRedisSubscriberResult.value.subscribe(getRedisProcessedEventsChannelName(this.betProvider, game.name, game.betType), message => {
await getRedisSubscriberResult.value.subscribe(getRedisProcessedEventsChannelName(this.betProvider, game.name, game.betType), async message => {
const parsedMessage = JSON.parse(message) as ProcessedGameEvents;
logger.trace("redis subscriber message received. ", parsedMessage)


/**
* TODO: Payload is really similar to DbTwoWayGameEvent / DbThreeWayGameEvent. Is there any way we can combine them?
* We are already using discriminated unions to correctly type case different game types.
*/
const innerResults = parsedMessage.data.map(async item => {
/**
* TODO: Check if games exists before attempting insert. (We shouldn't get double inserts as now as well due to unique constraints on the database)
*/
switch (item.type) {
case BetTypes.TWO_WAY:
const twoWayEventToDB: DbTwoWayGameEvent = {
betProviderName: parsedMessage.betProviderName,
betProviderId: item.betProviderId,
clubA: item.clubA,
clubB: item.clubB,
oddsAWin: item.oddsAWin,
oddsBWin: item.oddsBWin,
gameName: parsedMessage.gameName,
league: item.league,
metaData: item.meta
}
await insertTwoWayGameEvent(getPostgresDbResult.value, twoWayEventToDB);
break;
case BetTypes.THREE_WAY:
const threeWayEventToDb: DbThreeWayGameEvent = {
betProviderName: parsedMessage.betProviderName,
betProviderId: item.betProviderId,
clubA: item.clubA,
clubB: item.clubB,
oddsAWin: item.oddsAWin,
oddsBWin: item.oddsBWin,
oddsDraw: item.oddsDraw,
gameName: parsedMessage.gameName,
league: item.league,
metaData: item.meta
}
await insertThreeWayGameEvent(getPostgresDbResult.value, threeWayEventToDb);
break;
default:
const message = `Unknown bet type encountered when saving processed game events to database.`;
logger.error(message, item);
throw new Error(message);
}
});
await Promise.all(innerResults);
});
});
await Promise.all(results);
Expand Down
8 changes: 8 additions & 0 deletions src/core/parsers/betika/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export class BetikaParser extends BaseParser {
if (results2.result === "success") {
parsedResults = results2.value.map(item => {
return {
type: BetTypes.TWO_WAY,
betProviderId: item.link,
clubA: item.clubA,
clubB: item.clubB,
oddsAWin: item.oddsAWin,
oddsBWin: item.oddsBWin,
league: item.league,
Expand All @@ -84,6 +88,10 @@ export class BetikaParser extends BaseParser {
if (results2.result === "success") {
parsedResults = results2.value.map(item => {
return {
type: BetTypes.THREE_WAY,
betProviderId: item.link,
clubA: item.clubA,
clubB: item.clubB,
oddsAWin: item.oddsAWin,
oddsBWin: item.oddsBWin,
oddsDraw: item.oddsDraw,
Expand Down
9 changes: 8 additions & 1 deletion src/core/parsers/betika/parser_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ export function processBetikaThreeWayGamesHtml(html: string): Result<any[], Erro
link: $(clubsAndOdds).find("div.teams-info-vert-left > a").attr("href")
});
});
return {result: "success", value: gameEvents};

const filteredGameEvents = gameEvents.filter(event => {
return (event.oddsAWin !== null || event.oddsAWin !== undefined || !isNaN(event.oddsAWin)) &&
(event.oddsDraw !== null || event.oddsDraw !== undefined || !isNaN(event.oddsDraw)) &&
(event.oddsBWin !== null || event.oddsBWin !== undefined || !isNaN(event.oddsBWin));
});

return {result: "success", value: filteredGameEvents};
} catch (e: any) {
logger.error("An error occurred while parsing Betika two way html data: ", e.message);
return {result: "error", value: new Error(e.message)};
Expand Down
6 changes: 3 additions & 3 deletions src/datastores/postgres/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class TwoWayGameEventEntity {
id: number

@Index("two_way_game_event_provider_id_idx")
@Column("string", {length: 100, nullable: false})
@Column("varchar", {length: 100, nullable: false})
bet_provider_id: string

@Column("varchar", {length: 100, nullable: false})
Expand Down Expand Up @@ -59,7 +59,7 @@ export class ThreeWayGameEventEntity {
id: number

@Index("three_way_game_event_provider_id_idx")
@Column("string", {length: 100, nullable: false})
@Column("varchar", {length: 100, nullable: false})
bet_provider_id: string

@Column("varchar", {length: 100, nullable: false})
Expand All @@ -79,7 +79,7 @@ export class ThreeWayGameEventEntity {

@Index("three_way_game_event_bet_provider_idx")
@Column("varchar", {length: 100, nullable: false})
bet_provider: BetProviders
bet_provider_name: BetProviders

@Column("varchar", {length: 100, nullable: false})
game_name: Games
Expand Down
6 changes: 4 additions & 2 deletions src/datastores/postgres/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DataSource } from "typeorm";

import { Config, getConfig } from "../../index";
import { Result } from "../../utils/types/result_type/index";
import { ThreeWayGameEventEntity, TwoWayGameEventEntity } from "./entities";

const {logger} = getConfig();

Expand All @@ -19,13 +20,14 @@ export class PostgresDataSourceSingleton {
username: config.postgresUser,
password: config.postgresPassword,
database: config.postgresDatabaseName,
synchronize: false,
synchronize: true,
logging: false, // TODO: maybe create a different logging structure for database logs?
extra: {
sss: true
},
entities: [

TwoWayGameEventEntity,
ThreeWayGameEventEntity
]
});

Expand Down
24 changes: 15 additions & 9 deletions src/datastores/postgres/queries/three_way_game_event/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { DataSource, InsertResult, UpdateResult } from "typeorm";
import { BetProviders } from "../../../../utils/types/common";
import { ThreeWayGameEvent } from "../../../../utils/types/db";
import { DbThreeWayGameEvent } from "../../../../utils/types/db";
import { ThreeWayGameEventEntity } from "../../entities";
import { getConfig } from "../../../..";

const {logger} = getConfig();

/**
* Useful for checking whether a three way game event already exists for a provider.
Expand All @@ -26,21 +29,24 @@ export const getThreeWayGame = async (

export const insertThreeWayGameEvent = async (
dataSource: DataSource,
data: ThreeWayGameEvent
data: DbThreeWayGameEvent
): Promise<InsertResult> => {
const toDataBase = {
logger.trace("Inserting into database: ", data);
return await dataSource.createQueryBuilder()
.insert()
.into(ThreeWayGameEventEntity)
.values({
bet_provider_id: data.betProviderId,
bet_provider_name: data.betProviderName,
club_a: data.clubA,
club_b: data.clubB,
odds_a_win: data.oddsAWin,
odds_b_win: data.oddsBWin,
game_name: data.gameName
}
return await dataSource.createQueryBuilder()
.insert()
.into(ThreeWayGameEventEntity)
.values(toDataBase)
odds_draw: data.oddsDraw,
game_name: data.gameName,
league: data.league,
meta_data: data.metaData
})
.execute();
};

Expand Down
19 changes: 10 additions & 9 deletions src/datastores/postgres/queries/two_way_game_event/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DataSource, InsertResult, UpdateResult } from "typeorm";
import { BetProviders } from "../../../../utils/types/common";
import { TwoWayGameEvent } from "../../../../utils/types/db";
import { DbTwoWayGameEvent } from "../../../../utils/types/db";
import { TwoWayGameEventEntity } from "../../entities";

/**
Expand All @@ -26,21 +26,22 @@ export const getTwoWayGame = async (

export const insertTwoWayGameEvent = async (
dataSource: DataSource,
data: TwoWayGameEvent
data: DbTwoWayGameEvent
): Promise<InsertResult> => {
const toDataBase = {
return await dataSource.createQueryBuilder()
.insert()
.into(TwoWayGameEventEntity)
.values({
bet_provider_id: data.betProviderId,
bet_provider_name: data.betProviderName,
club_a: data.clubA,
club_b: data.clubB,
odds_a_win: data.oddsAWin,
odds_b_win: data.oddsBWin,
game_name: data.gameName
};
return await dataSource.createQueryBuilder()
.insert()
.into(TwoWayGameEventEntity)
.values(toDataBase)
game_name: data.gameName,
league: data.league,
meta_data: data.metaData
})
.execute();
};

Expand Down
4 changes: 2 additions & 2 deletions src/testbed/testbed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OrbitScrapper } from "../core/scrapping/orbit";
import { BetikaScrapper } from "../core/scrapping/betika";

const betikaScrapper = new OrbitScrapper();
const betikaScrapper = new BetikaScrapper();
betikaScrapper.fetchData();
4 changes: 2 additions & 2 deletions src/testbed/testbed_2.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OrbitParser } from "../core/parsers/orbit";
import { BetikaParser } from "../core/parsers/betika";

const parser = new OrbitParser()
const parser = new BetikaParser()
parser.subscribeToChannels();
4 changes: 4 additions & 0 deletions src/testbed/testbed_3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { BetikaGameEventsProcessor } from "../core/game_events/betika";

const gameEventsProcessor = new BetikaGameEventsProcessor();
gameEventsProcessor.subscribeToChannels();
1 change: 1 addition & 0 deletions src/utils/types/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export interface ProcessedHtmlMessage {
}

export interface BaseProcessedGameEvent {
betProviderId: string;
clubA: string,
clubB: string,
estimatedStartTimeUtc: Date,
Expand Down
4 changes: 2 additions & 2 deletions src/utils/types/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { BetProviders, Games } from "../common";

export interface TwoWayGameEvent {
export interface DbTwoWayGameEvent {
betProviderName: BetProviders;
betProviderId: string;
clubA: string;
Expand All @@ -18,7 +18,7 @@ export interface TwoWayGameEvent {
metaData: string;
}

export interface ThreeWayGameEvent {
export interface DbThreeWayGameEvent {
betProviderName: BetProviders;
betProviderId: string;
clubA: string;
Expand Down

0 comments on commit c06c4f2

Please sign in to comment.