package net.taehui.twilight.system import net.taehui.twilight.Logger import org.openqa.selenium.By import org.openqa.selenium.TimeoutException import org.openqa.selenium.WebDriver import org.openqa.selenium.edge.EdgeDriver import org.openqa.selenium.edge.EdgeOptions import org.openqa.selenium.support.ui.ExpectedConditions import org.openqa.selenium.support.ui.WebDriverWait import java.time.Duration import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit object TVSystem : Logger { class TVItem(val href: String, val title: String, val text: String) { override fun hashCode(): Int { return href.hashCode() } override fun equals(other: Any?): Boolean { return href == (other as TVItem).href } override fun toString(): String { return text } } private val ses: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor { Executors.defaultThreadFactory().newThread(it).apply { isDaemon = true } } private var targetSystem: WebDriver? = null fun handleSystem() { if (Configure.mode.tv) { try { targetSystem = EdgeDriver(EdgeOptions().apply { addArguments("--headless", "--no-sandbox") }) val pendingElements = mutableMapOf<TVItem, Int>() var lastElements = emptySet<TVItem>() ses.scheduleWithFixedDelay({ targetSystem?.get("https://www.twitch.tv/directory/game/Qwilight") val dataTest = By.cssSelector("[data-test-selector=TitleAndChannel]") val elements = try { WebDriverWait( targetSystem, Duration.ofSeconds(1) ).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(dataTest)) targetSystem?.findElements(dataTest) ?: throw TimeoutException() } catch (e: TimeoutException) { emptyList() }.map { TVItem( it.getAttribute("href"), it.findElement(By.tagName("h3")).text, it.findElement(By.tagName("p")).text ) }.toSet() elements.subtract(lastElements).filter { pendingElements.remove(it) == null }.forEach { SiteHandler.putSiteYell(it) } lastElements.subtract(elements).forEach { pendingElements[it] = 0 } pendingElements.toMap().forEach { if (it.value < 5) { pendingElements[it.key] = it.value + 1 } else { pendingElements.remove(it.key) } } lastElements = elements }, 0L, 1L, TimeUnit.MINUTES) } catch (e: Throwable) { logFault(e) } } } fun dispose() { ses.shutdown() ses.awaitTermination(1, TimeUnit.SECONDS) targetSystem?.quit() } }