Compare commits
No commits in common. "3d8306b225f10ee08b9ecf41a68f46afe0092dc6" and "15932a0c9d919228f66d80c08f3796bd67452d57" have entirely different histories.
3d8306b225
...
15932a0c9d
4 changed files with 187 additions and 167 deletions
146
dist/GameSource.js
vendored
146
dist/GameSource.js
vendored
|
@ -5,90 +5,100 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
const axios_1 = __importDefault(require("axios"));
|
const axios_1 = __importDefault(require("axios"));
|
||||||
const moment_1 = __importDefault(require("moment"));
|
const node_html_parser_1 = require("node-html-parser");
|
||||||
|
const moment_1 = __importDefault(require("moment")); // require
|
||||||
|
// This calss will be the game source.
|
||||||
|
// search for upcomming games
|
||||||
class GameSource {
|
class GameSource {
|
||||||
async getGamesFromHaifa(logger) {
|
async getGamesFromHaifa() {
|
||||||
console.log("Trying to get games from Haifa...");
|
const sourceUrl = `https://mhaifafc.com/games?lang=en`;
|
||||||
|
console.log('Trying to get games from Haifa...');
|
||||||
try {
|
try {
|
||||||
// Get the current date and time in the required format
|
const result = await axios_1.default.get(sourceUrl, {
|
||||||
const currentDate = (0, moment_1.default)().format("DD/MM/YYYY HH:mm");
|
headers: {
|
||||||
// Construct the filters object with the current date
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
|
||||||
const filters = {
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
|
||||||
date: {
|
'Accept-Language': 'en-US,en;q=0.9',
|
||||||
startDate: currentDate,
|
'Accept-Encoding': 'gzip, deflate, br',
|
||||||
endDate: "",
|
'DNT': '1',
|
||||||
},
|
'Connection': 'keep-alive',
|
||||||
league: "",
|
'Upgrade-Insecure-Requests': '1',
|
||||||
session: "",
|
|
||||||
gamesDirection: "1",
|
|
||||||
};
|
|
||||||
// Encode the filters for the URL
|
|
||||||
const filtersParam = encodeURIComponent(JSON.stringify(filters));
|
|
||||||
// Construct the API URL with the encoded filters
|
|
||||||
const sourceUrl = `https://api.mhaifafc.com/api/content/games-lobby?filters=${filtersParam}&start=0&limit=20&sortDirection=ASC&app=web&lang=he`;
|
|
||||||
// Get the authorization token from environment variables
|
|
||||||
const authorizationToken = process.env.HAIFA_API_AUTH_TOKEN;
|
|
||||||
// Set up the request headers
|
|
||||||
const headers = {
|
|
||||||
Accept: "*/*",
|
|
||||||
"Accept-Language": "en-US,en;q=0.7",
|
|
||||||
Authorization: `Bearer ${authorizationToken}`,
|
|
||||||
"User-Agent": "Mozilla/5.0",
|
|
||||||
Origin: "https://www.mhaifafc.com",
|
|
||||||
Referer: "https://www.mhaifafc.com/",
|
|
||||||
};
|
|
||||||
// Make the API request
|
|
||||||
const response = await axios_1.default.get(sourceUrl, {
|
|
||||||
headers,
|
|
||||||
responseType: "json",
|
|
||||||
responseEncoding: "utf8", // Ensure UTF-8 encoding
|
|
||||||
});
|
|
||||||
// Extract the games data from the response
|
|
||||||
const gamesData = response.data.games.items;
|
|
||||||
const games = [];
|
|
||||||
// Loop through each game and construct the GoogleCalendarEvent objects
|
|
||||||
for (const game of gamesData) {
|
|
||||||
const gameDetails = game.gameDetails;
|
|
||||||
const gameTime = gameDetails.gameTime; // ISO string
|
|
||||||
const isFinalGameDate = gameDetails.isFinalGameDate;
|
|
||||||
const gameLocation = gameDetails.gameLocation;
|
|
||||||
// Skip games without a game time
|
|
||||||
if (!gameTime)
|
|
||||||
continue;
|
|
||||||
const hostTeam = game.hostTeam;
|
|
||||||
const guestTeam = game.guestTeam;
|
|
||||||
// Get team names
|
|
||||||
const hostTeamName = hostTeam.teamName;
|
|
||||||
const guestTeamName = guestTeam.teamName;
|
|
||||||
const summary = `${hostTeamName} vs. ${guestTeamName}`;
|
|
||||||
// Include a note if the game date is not final
|
|
||||||
let description = `${hostTeamName} vs. ${guestTeamName}`;
|
|
||||||
if (!isFinalGameDate) {
|
|
||||||
description += " (Date and time are subject to change)";
|
|
||||||
}
|
}
|
||||||
// Calculate start and end times
|
});
|
||||||
const startDateTime = (0, moment_1.default)(gameTime).toISOString();
|
const parsedResult = (0, node_html_parser_1.parse)(result.data.toString());
|
||||||
const endDateTime = (0, moment_1.default)(gameTime).add(2, "hours").toISOString();
|
const gameBoxs = parsedResult.querySelectorAll(".game-box");
|
||||||
// Add the event to the games array
|
const games = [];
|
||||||
|
for (let gameBox of gameBoxs) {
|
||||||
|
const teamsPlaying = gameBox
|
||||||
|
.querySelectorAll(".team-name")
|
||||||
|
.map((team) => team.text);
|
||||||
|
const regex = /[\r\n\s]+/g;
|
||||||
|
const gameHeader = gameBox
|
||||||
|
.querySelector(".game-header")
|
||||||
|
.text.replace(regex, " ")
|
||||||
|
.trim();
|
||||||
|
const headerSplit = gameHeader.split(",");
|
||||||
|
// In data, if there is no time, it means it's the last game for the calender
|
||||||
|
const lastGameForCalender = headerSplit.length < 4;
|
||||||
|
const location = headerSplit[headerSplit.length - 1].trim();
|
||||||
|
if (location === 'נדחה')
|
||||||
|
continue;
|
||||||
|
if (lastGameForCalender)
|
||||||
|
break;
|
||||||
|
const gameDate = this.findDate(headerSplit);
|
||||||
|
const gameTime = this.findTime(headerSplit);
|
||||||
|
const start = (0, moment_1.default)(gameDate + gameTime, "DD/MM/YYYYHH:mm").toISOString();
|
||||||
|
const end = (0, moment_1.default)(gameDate + gameTime, "DD/MM/YYYYHH:mm")
|
||||||
|
.add(2, "hours")
|
||||||
|
.toISOString();
|
||||||
games.push({
|
games.push({
|
||||||
summary: summary,
|
summary: `${teamsPlaying[0]} vs. ${teamsPlaying[1]}`,
|
||||||
location: gameLocation,
|
location: headerSplit[headerSplit.length - 1].trim(),
|
||||||
description: description,
|
description: `${teamsPlaying[0]} vs. ${teamsPlaying[1]}`,
|
||||||
start: {
|
start: {
|
||||||
dateTime: startDateTime,
|
dateTime: start,
|
||||||
timeZone: "Asia/Jerusalem",
|
timeZone: "Asia/Jerusalem",
|
||||||
},
|
},
|
||||||
end: {
|
end: {
|
||||||
dateTime: endDateTime,
|
dateTime: end,
|
||||||
timeZone: "Asia/Jerusalem",
|
timeZone: "Asia/Jerusalem",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// return [];
|
||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return [];
|
}
|
||||||
|
}
|
||||||
|
findTime(headerSplit) {
|
||||||
|
let time = '';
|
||||||
|
headerSplit.forEach((item) => {
|
||||||
|
if (/\d{2}:\d{2}/.test(item)) {
|
||||||
|
time = item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return time.trim();
|
||||||
|
}
|
||||||
|
findDate(headerSplit) {
|
||||||
|
// if it's a date format, return it like: 19/08/2023
|
||||||
|
let date = '';
|
||||||
|
headerSplit.forEach((item) => {
|
||||||
|
if (/\d{2}\/\d{2}\/\d{4}/.test(item)) {
|
||||||
|
date = item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return date.trim();
|
||||||
|
}
|
||||||
|
getOpponentIndexByStadium(stadium) {
|
||||||
|
if (stadium === "Sammy Ofer Stadium") {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
dist/index.js
vendored
5
dist/index.js
vendored
|
@ -15,11 +15,12 @@ class App {
|
||||||
this.googleCalendar = new GoogleCalendar_1.default();
|
this.googleCalendar = new GoogleCalendar_1.default();
|
||||||
}
|
}
|
||||||
async startCronJob() {
|
async startCronJob() {
|
||||||
this.writeLog('START Haifa Reminder'); // Log when the cron job starts
|
this.writeLog('START CRON JOB'); // Log when the cron job starts
|
||||||
|
console.log("START Haifa Reminder");
|
||||||
const newGamesAdded = [];
|
const newGamesAdded = [];
|
||||||
await this.googleCalendar.init();
|
await this.googleCalendar.init();
|
||||||
try {
|
try {
|
||||||
const games = await this.gameSource.getGamesFromHaifa(this.writeLog);
|
const games = await this.gameSource.getGamesFromHaifa();
|
||||||
for (const game of games) {
|
for (const game of games) {
|
||||||
const isDuplicateEvent = await this.googleCalendar.isDuplicateEvent(game.start.dateTime, game.end.dateTime, game.summary);
|
const isDuplicateEvent = await this.googleCalendar.isDuplicateEvent(game.start.dateTime, game.end.dateTime, game.summary);
|
||||||
console.log(game);
|
console.log(game);
|
||||||
|
|
|
@ -1,106 +1,113 @@
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { GoogleCalendarEvent } from "./types";
|
import { GoogleCalendarEvent } from "./types";
|
||||||
import moment from "moment";
|
import { parse } from "node-html-parser";
|
||||||
|
import moment from "moment"; // require
|
||||||
|
|
||||||
|
// This calss will be the game source.
|
||||||
|
// search for upcomming games
|
||||||
|
|
||||||
export default class GameSource {
|
export default class GameSource {
|
||||||
async getGamesFromHaifa(logger: Function): Promise<GoogleCalendarEvent[]> {
|
async getGamesFromHaifa(): Promise<GoogleCalendarEvent[]> {
|
||||||
console.log("Trying to get games from Haifa...");
|
const sourceUrl = `https://mhaifafc.com/games?lang=en`;
|
||||||
|
console.log('Trying to get games from Haifa...');
|
||||||
try {
|
try {
|
||||||
// Get the current date and time in the required format
|
const result = await axios.get(sourceUrl,
|
||||||
const currentDate = moment().format("DD/MM/YYYY HH:mm");
|
{
|
||||||
|
headers: {
|
||||||
// Construct the filters object with the current date
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
|
||||||
const filters = {
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
|
||||||
date: {
|
'Accept-Language': 'en-US,en;q=0.9',
|
||||||
startDate: currentDate,
|
'Accept-Encoding': 'gzip, deflate, br',
|
||||||
endDate: "",
|
'DNT': '1',
|
||||||
},
|
'Connection': 'keep-alive',
|
||||||
league: "",
|
'Upgrade-Insecure-Requests': '1',
|
||||||
session: "",
|
}
|
||||||
gamesDirection: "1",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Encode the filters for the URL
|
|
||||||
const filtersParam = encodeURIComponent(JSON.stringify(filters));
|
|
||||||
|
|
||||||
// Construct the API URL with the encoded filters
|
|
||||||
const sourceUrl = `https://api.mhaifafc.com/api/content/games-lobby?filters=${filtersParam}&start=0&limit=20&sortDirection=ASC&app=web&lang=he`;
|
|
||||||
|
|
||||||
// Get the authorization token from environment variables
|
|
||||||
const authorizationToken = process.env.HAIFA_API_AUTH_TOKEN;
|
|
||||||
|
|
||||||
// Set up the request headers
|
|
||||||
const headers = {
|
|
||||||
Accept: "*/*",
|
|
||||||
"Accept-Language": "en-US,en;q=0.7",
|
|
||||||
Authorization: `Bearer ${authorizationToken}`,
|
|
||||||
"User-Agent": "Mozilla/5.0",
|
|
||||||
Origin: "https://www.mhaifafc.com",
|
|
||||||
Referer: "https://www.mhaifafc.com/",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make the API request
|
|
||||||
const response = await axios.get(sourceUrl, {
|
|
||||||
headers,
|
|
||||||
responseType: "json", // Ensure the response is parsed as JSON
|
|
||||||
responseEncoding: "utf8", // Ensure UTF-8 encoding
|
|
||||||
});
|
|
||||||
|
|
||||||
// Extract the games data from the response
|
|
||||||
const gamesData = response.data.games.items;
|
|
||||||
|
|
||||||
const games: GoogleCalendarEvent[] = [];
|
|
||||||
|
|
||||||
// Loop through each game and construct the GoogleCalendarEvent objects
|
|
||||||
for (const game of gamesData) {
|
|
||||||
const gameDetails = game.gameDetails;
|
|
||||||
const gameTime = gameDetails.gameTime; // ISO string
|
|
||||||
const isFinalGameDate = gameDetails.isFinalGameDate;
|
|
||||||
const gameLocation = gameDetails.gameLocation;
|
|
||||||
|
|
||||||
// Skip games without a game time
|
|
||||||
if (!gameTime) continue;
|
|
||||||
|
|
||||||
const hostTeam = game.hostTeam;
|
|
||||||
const guestTeam = game.guestTeam;
|
|
||||||
|
|
||||||
// Get team names
|
|
||||||
const hostTeamName = hostTeam.teamName;
|
|
||||||
const guestTeamName = guestTeam.teamName;
|
|
||||||
|
|
||||||
const summary = `${hostTeamName} vs. ${guestTeamName}`;
|
|
||||||
|
|
||||||
// Include a note if the game date is not final
|
|
||||||
let description = `${hostTeamName} vs. ${guestTeamName}`;
|
|
||||||
if (!isFinalGameDate) {
|
|
||||||
description += " (Date and time are subject to change)";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate start and end times
|
|
||||||
const startDateTime = moment(gameTime).toISOString();
|
|
||||||
const endDateTime = moment(gameTime).add(2, "hours").toISOString();
|
|
||||||
|
|
||||||
// Add the event to the games array
|
|
||||||
games.push({
|
|
||||||
summary: summary,
|
|
||||||
location: gameLocation,
|
|
||||||
description: description,
|
|
||||||
start: {
|
|
||||||
dateTime: startDateTime,
|
|
||||||
timeZone: "Asia/Jerusalem",
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
dateTime: endDateTime,
|
|
||||||
timeZone: "Asia/Jerusalem",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const parsedResult = parse(result.data.toString());
|
||||||
|
const gameBoxs = parsedResult.querySelectorAll(".game-box");
|
||||||
|
|
||||||
|
const games: GoogleCalendarEvent[] = [];
|
||||||
|
|
||||||
|
for (let gameBox of gameBoxs) {
|
||||||
|
const teamsPlaying = gameBox
|
||||||
|
.querySelectorAll(".team-name")
|
||||||
|
.map((team: any) => team.text);
|
||||||
|
const regex = /[\r\n\s]+/g;
|
||||||
|
const gameHeader = gameBox
|
||||||
|
.querySelector(".game-header")
|
||||||
|
.text.replace(regex, " ")
|
||||||
|
.trim();
|
||||||
|
const headerSplit = gameHeader.split(",");
|
||||||
|
|
||||||
|
// In data, if there is no time, it means it's the last game for the calender
|
||||||
|
const lastGameForCalender = headerSplit.length < 4;
|
||||||
|
const location = headerSplit[headerSplit.length - 1].trim();
|
||||||
|
|
||||||
|
if (location === 'נדחה') continue;
|
||||||
|
if (lastGameForCalender) break;
|
||||||
|
|
||||||
|
const gameDate = this.findDate(headerSplit);
|
||||||
|
const gameTime = this.findTime(headerSplit);
|
||||||
|
|
||||||
|
const start = moment(
|
||||||
|
gameDate + gameTime,
|
||||||
|
"DD/MM/YYYYHH:mm"
|
||||||
|
).toISOString();
|
||||||
|
const end = moment(gameDate + gameTime, "DD/MM/YYYYHH:mm")
|
||||||
|
.add(2, "hours")
|
||||||
|
.toISOString();
|
||||||
|
|
||||||
|
games.push({
|
||||||
|
summary: `${teamsPlaying[0]} vs. ${teamsPlaying[1]}`,
|
||||||
|
location: headerSplit[headerSplit.length - 1].trim(),
|
||||||
|
description: `${teamsPlaying[0]} vs. ${teamsPlaying[1]}`,
|
||||||
|
start: {
|
||||||
|
dateTime: start,
|
||||||
|
timeZone: "Asia/Jerusalem",
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
dateTime: end,
|
||||||
|
timeZone: "Asia/Jerusalem",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// return [];
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private findTime(headerSplit: string[]) {
|
||||||
|
let time = '';
|
||||||
|
headerSplit.forEach((item) => {
|
||||||
|
if (/\d{2}:\d{2}/.test(item)) {
|
||||||
|
time = item;
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return games;
|
});
|
||||||
} catch (error) {
|
return time.trim();
|
||||||
console.error(error);
|
}
|
||||||
return [];
|
private findDate(headerSplit: string[]) {
|
||||||
|
// if it's a date format, return it like: 19/08/2023
|
||||||
|
let date = '';
|
||||||
|
headerSplit.forEach((item) => {
|
||||||
|
if(/\d{2}\/\d{2}\/\d{4}/.test(item)) {
|
||||||
|
date = item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return date.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
getOpponentIndexByStadium(stadium: string) {
|
||||||
|
if (stadium === "Sammy Ofer Stadium") {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,13 @@ class App {
|
||||||
}
|
}
|
||||||
|
|
||||||
async startCronJob() {
|
async startCronJob() {
|
||||||
this.writeLog('START Haifa Reminder'); // Log when the cron job starts
|
this.writeLog('START CRON JOB'); // Log when the cron job starts
|
||||||
|
console.log("START Haifa Reminder");
|
||||||
const newGamesAdded = [];
|
const newGamesAdded = [];
|
||||||
await this.googleCalendar.init();
|
await this.googleCalendar.init();
|
||||||
try {
|
try {
|
||||||
const games = await this.gameSource.getGamesFromHaifa(this.writeLog);
|
const games = await this.gameSource.getGamesFromHaifa();
|
||||||
|
|
||||||
for (const game of games) {
|
for (const game of games) {
|
||||||
const isDuplicateEvent = await this.googleCalendar.isDuplicateEvent(
|
const isDuplicateEvent = await this.googleCalendar.isDuplicateEvent(
|
||||||
game.start.dateTime,
|
game.start.dateTime,
|
||||||
|
|
Loading…
Reference in a new issue