<commit_before>package net.perfectdreams.loritta.utils

import com.mrpowergamerbr.loritta.network.Databases
import mu.KotlinLogging
import net.perfectdreams.loritta.tables.Backgrounds
import net.perfectdreams.loritta.tables.DailyShopItems
import net.perfectdreams.loritta.tables.DailyShops
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.transactions.transaction

class LorittaDailyShopUpdateTask : Runnable {
	companion object {
		private val logger = KotlinLogging.logger {}
		// How many new items should be shown in the shop on every shop rotation?
		// This exists to avoid Lori always selecting previously sold items instead of selecting never seen before items
		private const val NEW_ITEMS_TARGET = 2
		private const val DAILY_BACKGROUNDS_TARGET = 10

		fun generate() {
			logger.info { "Generating a new daily shop..." }
			transaction(Databases.loritta) {
				val newShop = DailyShops.insertAndGetId {
					it[generatedAt] = System.currentTimeMillis()
				}

				val allBackgrounds = Backgrounds.select {
					Backgrounds.enabled eq true and (Backgrounds.availableToBuyViaDreams eq true)
				}.toMutableList()

				val selectedBackgrounds = mutableListOf<ResultRow>()

				// We will try to at least have two new items every single day, to avoid showing already sold backgrounds every day
				val neverSoldBeforeBackgrounds = allBackgrounds.filter {
					DailyShopItems.select {
						DailyShopItems.item eq it[Backgrounds.id]
					}.count() == 0L
				}

				if (neverSoldBeforeBackgrounds.isNotEmpty()) {
					repeat(Math.min(NEW_ITEMS_TARGET, neverSoldBeforeBackgrounds.size)) {
						val randomBackground = neverSoldBeforeBackgrounds.random()
						allBackgrounds.remove(randomBackground)
						neverSoldBeforeBackgrounds.remove(randomBackground)
						selectedBackgrounds.add(randomBackground)
					}
				}

				repeat(DAILY_BACKGROUNDS_TARGET - selectedBackgrounds.size) {
					val randomBackground = allBackgrounds.random()
					allBackgrounds.remove(randomBackground)
					selectedBackgrounds.add(randomBackground)
				}

				for (background in selectedBackgrounds) {
					DailyShopItems.insert {
						it[shop] = newShop
						it[item] = background[Backgrounds.id]
						it[tag] = if (DailyShopItems.select { item eq background[Backgrounds.id] }.count() == 0L) { "website.dailyShop.new" } else null
					}<commit_msg>Fix never seen before backgrounds being repeated<commit_after>package net.perfectdreams.loritta.utils

import com.mrpowergamerbr.loritta.network.Databases
import mu.KotlinLogging
import net.perfectdreams.loritta.tables.Backgrounds
import net.perfectdreams.loritta.tables.DailyShopItems
import net.perfectdreams.loritta.tables.DailyShops
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.transactions.transaction

class LorittaDailyShopUpdateTask : Runnable {
	companion object {
		private val logger = KotlinLogging.logger {}
		// How many new items should be shown in the shop on every shop rotation?
		// This exists to avoid Lori always selecting previously sold items instead of selecting never seen before items
		private const val NEW_ITEMS_TARGET = 2
		private const val DAILY_BACKGROUNDS_TARGET = 10

		fun generate() {
			logger.info { "Generating a new daily shop..." }
			transaction(Databases.loritta) {
				val newShop = DailyShops.insertAndGetId {
					it[generatedAt] = System.currentTimeMillis()
				}

				val allBackgrounds = Backgrounds.select {
					Backgrounds.enabled eq true and (Backgrounds.availableToBuyViaDreams eq true)
				}.toMutableList()

				val selectedBackgrounds = mutableListOf<ResultRow>()

				// We will try to at least have two new items every single day, to avoid showing already sold backgrounds every day
				val neverSoldBeforeBackgrounds = allBackgrounds.filter {
					DailyShopItems.select {
						DailyShopItems.item eq it[Backgrounds.id]
					}.count() == 0L
				}.toMutableList()

				if (neverSoldBeforeBackgrounds.isNotEmpty()) {
					repeat(Math.min(NEW_ITEMS_TARGET, neverSoldBeforeBackgrounds.size)) {
						val randomBackground = neverSoldBeforeBackgrounds.random()
						// We need to do this because the ResultRow isn't the same instance
						// TODO: Check if this is really true, I'm 99% sure it is, but...
						allBackgrounds.removeIf { it[Backgrounds.internalName] == randomBackground[Backgrounds.internalName] }
						neverSoldBeforeBackgrounds.remove(randomBackground)
						selectedBackgrounds.add(randomBackground)
					}
				}

				repeat(DAILY_BACKGROUNDS_TARGET - selectedBackgrounds.size) {
					val randomBackground = allBackgrounds.random()
					allBackgrounds.remove(randomBackground)
					selectedBackgrounds.add(randomBackground)
				}

				for (background in selectedBackgrounds) {
					DailyShopItems.insert {
						it[shop] = newShop
						it[item] = background[Backgrounds.id]
						it[tag] = if (DailyShopItems.select { item eq background[Backgrounds.id] }.count() == 0L) { "website.dailyShop.new" } else null
					}
{'fraction_non_alphanumeric': 0.08100668501769563, 'fraction_numerical': 0.0023594180102241447, 'mean_word_length': 4.122860020140987, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3441360', 'n_tokens_mistral': 1787, 'n_tokens_neox': 1419, 'n_words': 360}