big refactoring of none_of_that handler
extracting, better typing, reduction of complexity
This commit is contained in:
		@@ -34,8 +34,9 @@ export default class VoteController {
 | 
			
		||||
		this.yavinJellyfinHandler = _yavin
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public async handleNoneOfThatVote(messageReaction: MessageReaction, user: User, reactedUponMessage: VoteMessage, requestId: string, guildId: string) {
 | 
			
		||||
	public async handleNoneOfThatVote(messageReaction: MessageReaction, reactedUponMessage: VoteMessage, requestId: string, guildId: string) {
 | 
			
		||||
		if (!messageReaction.message.guild) return 'No guild'
 | 
			
		||||
		const guild = messageReaction.message.guild
 | 
			
		||||
		logger.debug(`${reactedUponMessage.id} is vote message`, { requestId, guildId })
 | 
			
		||||
 | 
			
		||||
		const watcherRoleMember = await getMembersWithRoleFromGuild(config.bot.announcement_role, messageReaction.message.guild)
 | 
			
		||||
@@ -44,52 +45,58 @@ export default class VoteController {
 | 
			
		||||
		const watcherRoleMemberCount = watcherRoleMember.size
 | 
			
		||||
		logger.info(`MEMBER COUNT: ${watcherRoleMemberCount}`, { requestId, guildId })
 | 
			
		||||
 | 
			
		||||
		const noneOfThatReactions = messageReaction.message.reactions.cache.get(NONE_OF_THAT)?.users.cache.filter(x => x.id !== this.client.user?.id).size ?? 0
 | 
			
		||||
		const noneOfThatReactions = reactedUponMessage.reactions.cache.get(NONE_OF_THAT)?.users.cache.filter(x => x.id !== this.client.user?.id).size ?? 0
 | 
			
		||||
 | 
			
		||||
		const memberThreshold = (watcherRoleMemberCount / 2)
 | 
			
		||||
		logger.info(`Reroll ${noneOfThatReactions} > ${memberThreshold} ?`, { requestId, guildId })
 | 
			
		||||
		if (noneOfThatReactions > memberThreshold) {
 | 
			
		||||
		if (noneOfThatReactions > memberThreshold)
 | 
			
		||||
			logger.info(`No reroll`, { requestId, guildId })
 | 
			
		||||
		else
 | 
			
		||||
			logger.info('Starting poll reroll', { requestId, guildId })
 | 
			
		||||
			messageReaction.message.edit((messageReaction.message.content ?? "").concat('\nDiese Abstimmung muss wiederholt werden.'))
 | 
			
		||||
			// get movies that _had_ votes
 | 
			
		||||
			//const oldMovieNames: Vote[] = this.parseVotesFromVoteMessage(messageReaction.message, requestId)
 | 
			
		||||
			const parsedIds = this.parseGuildIdAndEventIdFromWholeMessage(messageReaction.message.cleanContent ?? '')
 | 
			
		||||
			const eventStartDate: Date = this.fetchEventStartDateByEventId(parsedIds.eventId, requestId) //TODO
 | 
			
		||||
			//
 | 
			
		||||
			// get movies from jellyfin to fill the remaining slots
 | 
			
		||||
			const newMovieCount = config.bot.random_movie_count //- oldMovieNames.length
 | 
			
		||||
			const newMovies = await this.yavinJellyfinHandler.getRandomMovieNames(newMovieCount, guildId, requestId)
 | 
			
		||||
		await this.handleReroll(reactedUponMessage, guild, guild.id, requestId)
 | 
			
		||||
	}
 | 
			
		||||
	public async handleReroll(voteMessage: VoteMessage, guild: Guild, guildId: string, requestId: string) {
 | 
			
		||||
 | 
			
		||||
			// merge
 | 
			
		||||
			const movies = newMovies
 | 
			
		||||
		//get movies that already had votes to give them a second chance
 | 
			
		||||
		const voteInfo = await this.parseVoteInfoFromVoteMessage(voteMessage, requestId)
 | 
			
		||||
 | 
			
		||||
			// create new message
 | 
			
		||||
			await this.closePoll(messageReaction.message.guild, requestId)
 | 
			
		||||
			const message = this.createVoteMessageText(parsedIds.guildId, eventStartDate, movies, guildId, requestId)
 | 
			
		||||
			const announcementChannel = this.client.getAnnouncementChannelForGuild(guildId)
 | 
			
		||||
			if (!announcementChannel) {
 | 
			
		||||
				logger.error(`No announcementChannel found for ${guildId}, can't post poll`)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			const sentMessage = await this.sendVoteMessage(message, movies.length, announcementChannel)
 | 
			
		||||
			sentMessage.pin()
 | 
			
		||||
		// get movies from jellyfin to fill the remaining slots
 | 
			
		||||
		const newMovieCount = config.bot.random_movie_count - voteInfo.votes.filter(x => x.count > 2).length
 | 
			
		||||
		const newMovies = await this.yavinJellyfinHandler.getRandomMovieNames(newMovieCount, guildId, requestId)
 | 
			
		||||
 | 
			
		||||
		// merge
 | 
			
		||||
		const movies = newMovies.concat(voteInfo.votes.map(x => x.movie))
 | 
			
		||||
 | 
			
		||||
		// create new message
 | 
			
		||||
		await this.closePoll(guild, requestId)
 | 
			
		||||
		const message = this.createVoteMessageText(guild.id, voteInfo.eventDate, movies, guildId, requestId)
 | 
			
		||||
		const announcementChannel = this.client.getAnnouncementChannelForGuild(guildId)
 | 
			
		||||
		if (!announcementChannel) {
 | 
			
		||||
			logger.error(`No announcementChannel found for ${guildId}, can't post poll`)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		logger.info(`No reroll`, { requestId, guildId })
 | 
			
		||||
		const sentMessage = await this.sendVoteMessage(message, movies.length, announcementChannel)
 | 
			
		||||
		sentMessage.pin()
 | 
			
		||||
	}
 | 
			
		||||
	private fetchEventStartDateByEventId(eventId: string, requestId: string): Date {
 | 
			
		||||
		throw new Error("Method not implemented.")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private async fetchEventStartDateByEventId(guild: Guild, eventId: string, requestId: string): Promise<Maybe<Date>> {
 | 
			
		||||
		const guildEvent: GuildScheduledEvent = await guild.scheduledEvents.fetch(eventId)
 | 
			
		||||
		if (!guildEvent) logger.error(`GuildScheduledEvent with id${eventId} could not be found`, { requestId, guildId: guild.id })
 | 
			
		||||
		if (guildEvent.scheduledStartAt)
 | 
			
		||||
			return guildEvent.scheduledStartAt
 | 
			
		||||
	}
 | 
			
		||||
	public parseGuildIdAndEventIdFromWholeMessage(message: string) {
 | 
			
		||||
		const idmatch = RegExp(/(?:http|https):\/\/discord\.com\/events\/(\d*)\/(\d*)/)
 | 
			
		||||
		const matches = message.match(idmatch)
 | 
			
		||||
		if (matches && matches.length == 3)
 | 
			
		||||
			return { guildId: matches[1], eventId: matches[2] }
 | 
			
		||||
		throw Error(`Could not find eventId in Vote Message`)
 | 
			
		||||
	}
 | 
			
		||||
	public parseVotesFromVoteMessage(message: VoteMessage, requestId: string): VoteMessageInfo {
 | 
			
		||||
 | 
			
		||||
	public async parseVoteInfoFromVoteMessage(message: VoteMessage, requestId: string): Promise<VoteMessageInfo> {
 | 
			
		||||
		const lines = message.cleanContent.split('\n')
 | 
			
		||||
		let parsedIds = this.parseGuildIdAndEventIdFromWholeMessage(message.cleanContent)
 | 
			
		||||
		let eventDate: Date = this.parseEventDateFromMessage(message.cleanContent)
 | 
			
		||||
 | 
			
		||||
		if (!message.guild)
 | 
			
		||||
			throw new Error(`Message ${message.id} not a guild message`)
 | 
			
		||||
 | 
			
		||||
		let eventStartDate: Maybe<Date> = await this.fetchEventStartDateByEventId(message.guild, parsedIds.eventId, requestId)
 | 
			
		||||
		if (!eventStartDate) eventStartDate = this.parseEventDateFromMessage(message.cleanContent, message.guild.id, requestId)
 | 
			
		||||
 | 
			
		||||
		let votes: Vote[] = []
 | 
			
		||||
		for (const line of lines) {
 | 
			
		||||
			if (line.slice(0, 5).includes(':')) {
 | 
			
		||||
@@ -107,18 +114,25 @@ export default class VoteController {
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return <VoteMessageInfo>{ eventId: parsedIds.eventId, eventDate, votes }
 | 
			
		||||
		return <VoteMessageInfo>{ eventId: parsedIds.eventId, eventDate: eventStartDate, votes }
 | 
			
		||||
	}
 | 
			
		||||
	public parseEventDateFromMessage(message: string): Date {
 | 
			
		||||
	public parseEventDateFromMessage(message: string, guildId: string, requestId: string): Date {
 | 
			
		||||
		logger.warn(`Falling back to RegEx parsing to get Event Date`, { guildId, requestId })
 | 
			
		||||
		const datematcher = RegExp(/((?:0[1-9]|[12][0-9]|3[01])\.(?:0[1-9]|1[012])\.)(?:\ um\ )((?:(?:[01][0-9]|[2][0-3])\:[0-5][0-9])|(?:[2][4]\:00))!/i)
 | 
			
		||||
		const result: RegExpMatchArray | null = message.match(datematcher)
 | 
			
		||||
		const timeFromResult = result?.at(-1)
 | 
			
		||||
		const dateFromResult = result?.at(1)?.concat(format(new Date(), 'yyyy')).concat(" " + timeFromResult) ?? ""
 | 
			
		||||
		return new Date(dateFromResult)
 | 
			
		||||
	}
 | 
			
		||||
	public parseGuildIdAndEventIdFromWholeMessage(message: string) {
 | 
			
		||||
		const idmatch = RegExp(/(?:http|https):\/\/discord\.com\/events\/(\d*)\/(\d*)/)
 | 
			
		||||
		const matches = message.match(idmatch)
 | 
			
		||||
		if (matches && matches.length == 3)
 | 
			
		||||
			return { guildId: matches[1], eventId: matches[2] }
 | 
			
		||||
		throw Error(`Could not find eventId in Vote Message`)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public createVoteMessageText(eventId: string, eventStartDate: Date, movies: string[], guildId: string, requestId: string): string {
 | 
			
		||||
 | 
			
		||||
		let message = `[Abstimmung] für https://discord.com/events/${guildId}/${eventId} \n<@&${config.bot.announcement_role}> Es gibt eine neue Abstimmung für die nächste Watchparty ${createDateStringFromEvent(eventStartDate, guildId, requestId)}! Stimme hierunter für den nächsten Film ab!\n`
 | 
			
		||||
 | 
			
		||||
		for (let i = 0; i < movies.length; i++) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user