From 479978675b2be0448396ffccda0693f9b2b8f7bd Mon Sep 17 00:00:00 2001 From: psuwala Date: Mon, 17 Jul 2023 14:38:47 +0200 Subject: [PATCH] changed ical to old api --- src/main.ts | 4 +- src/meetup/MeetupApiAdapter.ts | 133 +++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/meetup/MeetupApiAdapter.ts diff --git a/src/main.ts b/src/main.ts index 54096a4..9ff9da3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,8 @@ import "dotenv/config"; -import { MeetupAdapter } from "./meetup/MeetupAdapter"; import { SimpleEventPublisher } from "./publisher/SimpleEventPublisher"; import { DiscordAdapter } from "./discord/DiscordAdapter"; +import { MeetupApiAdapter } from "./meetup/MeetupApiAdapter"; function safeRunWithInterval(cb: () => void | Promise, interval: number) { const safeCb = async () => { @@ -26,7 +26,7 @@ export async function runApplication() { const eventPublisher = new SimpleEventPublisher(); await DiscordAdapter.createWithSqlite(eventPublisher); - const meetupAdapter = await MeetupAdapter.createWithSQlite( + const meetupAdapter = await MeetupApiAdapter.createWithSQlite( eventPublisher, meetup_group_name ); diff --git a/src/meetup/MeetupApiAdapter.ts b/src/meetup/MeetupApiAdapter.ts new file mode 100644 index 0000000..df3cb56 --- /dev/null +++ b/src/meetup/MeetupApiAdapter.ts @@ -0,0 +1,133 @@ +import MeetupEvent from "./MeetupEvent"; +import { + MeetupEventRepository, + KnexMeetupEventRepository, + DatabaseEntry, +} from "./EventRepository"; +import { EventPublisher } from "../publisher/EventPublisher"; +import { createSqliteDb } from "../common/utils/db"; + +import axios from "axios"; + +// https://api.meetup.com/hspomorze/events +interface ComparisonResult { + newEvents: MeetupEvent[]; + modifiedEvents: MeetupEvent[]; +} + +export interface MeetupAdapterI { + trigger(): Promise; +} + +export class MeetupApiAdapter implements MeetupAdapterI { + constructor( + protected eventRepository: MeetupEventRepository, + protected publisher: EventPublisher, + protected groupName: string + ) {} + + async trigger() { + const events = await this.getUpdates(); + + await this.publishEvents(events); + await this.storeEvents(events); + } + + protected async getUpdates() { + const freshEvents = await this.fetchMeetupEvents(); + const lastEvents = await this.eventRepository.getAll(); + + return this.compareEvents(lastEvents, freshEvents); + } + + protected async fetchMeetupEvents(): Promise { + const url = encodeURI(`https://api.meetup.com/${this.groupName}/events`); + const response = await axios.get(url); + const data = response.data as Array; + + return data.map( + (x) => + new MeetupEvent( + x.name as string, + x.description as string, + x.venue.name as string, + x.link as string, + x.id as string, + new Date(x.updated as number), + new Date(x.time as number), + new Date(((x.time as number) + x.duration) as number) + ) + ); + } + + protected compareEvents( + oldEvents: DatabaseEntry[], + freshEvents: MeetupEvent[] + ): ComparisonResult { + const newEvents: MeetupEvent[] = []; + const modifiedEvents: MeetupEvent[] = []; + + freshEvents.forEach((freshEvent) => { + const matchingOldEvent = oldEvents.find( + (oldEvent) => oldEvent.uid === freshEvent.uid + ); + + if (matchingOldEvent === undefined) { + newEvents.push(freshEvent); + } else { + if (matchingOldEvent.lastModified !== freshEvent.lastModified) + modifiedEvents.push(freshEvent); + } + }); + + return { + newEvents, + modifiedEvents, + }; + } + + protected async publishEvents(events: ComparisonResult): Promise { + const handlers: Promise[] = []; + + events.newEvents.forEach((event) => { + const message = event.toEventCreatedMessage(); + const handler = this.publisher.publish(message); + handlers.push(handler); + }); + events.modifiedEvents.forEach((event) => { + const message = event.toEventModifiedMessage(); + const handler = this.publisher.publish(message); + handlers.push(handler); + }); + + await Promise.all(handlers); + } + + protected async storeEvents(events: ComparisonResult): Promise { + const handlers: Promise[] = []; + + events.newEvents.forEach((event) => { + const handler = this.eventRepository.addEvent(event); + handlers.push(handler); + }); + events.modifiedEvents.forEach((event) => { + const handler = this.eventRepository.updateEvent(event.uid, event); + handlers.push(handler); + }); + + await Promise.all(handlers); + } + + static async createWithSQlite(publisher: EventPublisher, groupName: string) { + const db = createSqliteDb("meetup.db"); + + const meetupRepo = await KnexMeetupEventRepository.create(db); + const meetupAdapter = new MeetupApiAdapter( + meetupRepo, + publisher, + groupName + ); + + return meetupAdapter; + } +}