adding version update
This commit is contained in:
		@@ -1,16 +1,21 @@
 | 
				
			|||||||
package net.xintanalabs.rssotto.components.checkers.scrape
 | 
					package net.xintanalabs.rssotto.components.checkers.scrape
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import kotlinx.coroutines.delay
 | 
				
			||||||
import org.jsoup.Jsoup
 | 
					import org.jsoup.Jsoup
 | 
				
			||||||
import org.springframework.stereotype.Component
 | 
					import org.springframework.stereotype.Component
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component("jsoup")
 | 
					@Component("jsoup")
 | 
				
			||||||
class JSoupFetcher: IScrapeFetcher {
 | 
					class JSoupFetcher: IScrapeFetcher {
 | 
				
			||||||
    override suspend fun fetch(url: String): String {
 | 
					    override suspend fun fetch(url: String): String {
 | 
				
			||||||
 | 
					        delay(1000) // 1-second delay to avoid rate limiting
 | 
				
			||||||
        return try {
 | 
					        return try {
 | 
				
			||||||
            Jsoup.connect(url)
 | 
					            Jsoup.connect(url)
 | 
				
			||||||
                .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
 | 
					                .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
 | 
				
			||||||
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
 | 
					                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
 | 
				
			||||||
                .header("Accept-Language", "en-US,en;q=0.5")
 | 
					                .header("Accept-Language", "en-US,en;q=0.5")
 | 
				
			||||||
 | 
					                .header("Accept-Encoding", "gzip, deflate")
 | 
				
			||||||
 | 
					                //.header("Connection", "keep-alive")
 | 
				
			||||||
 | 
					                .header("Upgrade-Insecure-Requests", "1")
 | 
				
			||||||
                .get()
 | 
					                .get()
 | 
				
			||||||
                .html()
 | 
					                .html()
 | 
				
			||||||
        } catch (e: Exception) {
 | 
					        } catch (e: Exception) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,7 @@ class ScrapeChecker(
 | 
				
			|||||||
        val response = fetcher.fetch(url)
 | 
					        val response = fetcher.fetch(url)
 | 
				
			||||||
        val cleanedResponse = response.replace(">\\s+<".toRegex(), "><")
 | 
					        val cleanedResponse = response.replace(">\\s+<".toRegex(), "><")
 | 
				
			||||||
        log.info("Response : {}", cleanedResponse)
 | 
					        log.info("Response : {}", cleanedResponse)
 | 
				
			||||||
        val regex = paramsDict["regex"]
 | 
					        val regex: String = paramsDict["regex"] as String
 | 
				
			||||||
        log.info("Regex : {}", regex)
 | 
					        log.info("Regex : {}", regex)
 | 
				
			||||||
        val match = Pattern.compile(regex).matcher(cleanedResponse)
 | 
					        val match = Pattern.compile(regex).matcher(cleanedResponse)
 | 
				
			||||||
        if (!match.find() || match.groupCount() < 1) {
 | 
					        if (!match.find() || match.groupCount() < 1) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,9 +15,10 @@ data class App(
 | 
				
			|||||||
    val fields: Map<String, String>,
 | 
					    val fields: Map<String, String>,
 | 
				
			||||||
    val downloadUrl: String,
 | 
					    val downloadUrl: String,
 | 
				
			||||||
    val currentVersion: String,
 | 
					    val currentVersion: String,
 | 
				
			||||||
    val latestVersion: String,
 | 
					    val latestVersion: String? = null,
 | 
				
			||||||
    val status: AppStatus,
 | 
					    val status: AppStatus,
 | 
				
			||||||
    val createdAt: Long = 0,
 | 
					    val createdAt: Long = 0,
 | 
				
			||||||
    val updatedAt: Long = 0,
 | 
					    val updatedAt: Long = 0,
 | 
				
			||||||
    val lastCheckedAt: Long = 0
 | 
					    val lastCheckedAt: Long = 0,
 | 
				
			||||||
 | 
					    val active: Boolean = true
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,7 @@ class AppService(private val mongoDBClient: MongoDBClient) {
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
            return mongoDBClient.updateOne(
 | 
					            return mongoDBClient.updateOne(
 | 
				
			||||||
                collection,
 | 
					                collection,
 | 
				
			||||||
                "uid",
 | 
					                "_id",
 | 
				
			||||||
                id,
 | 
					                id,
 | 
				
			||||||
                updateFields,
 | 
					                updateFields,
 | 
				
			||||||
                App::class.java
 | 
					                App::class.java
 | 
				
			||||||
@@ -68,4 +68,21 @@ class AppService(private val mongoDBClient: MongoDBClient) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun updateLatestVersion(appId: String, latestVersion: String): Long {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            val updateFields = mapOf<String, String>(
 | 
				
			||||||
 | 
					                "latestVersion" to latestVersion
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return mongoDBClient.updateOne(
 | 
				
			||||||
 | 
					                collection,
 | 
				
			||||||
 | 
					                "_id",
 | 
				
			||||||
 | 
					                appId,
 | 
				
			||||||
 | 
					                updateFields,
 | 
				
			||||||
 | 
					                App::class.java
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        } catch (e: Exception) {
 | 
				
			||||||
 | 
					            throw RuntimeException("Failed to update app: ${e.message}", e)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -6,7 +6,7 @@ import net.xintanalabs.rssotto.model.CheckerType
 | 
				
			|||||||
import org.springframework.stereotype.Service
 | 
					import org.springframework.stereotype.Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
class CheckerTypeService (mongoDBClient: MongoDBClient) : ServiceBase<CheckerType>(mongoDBClient){
 | 
					class CheckerTypeService (mongoDBClient: MongoDBClient) : ServiceMongoDBBase<CheckerType>(mongoDBClient){
 | 
				
			||||||
    override val collection: String = Constants.COLLECTION_CHECKER_TYPES
 | 
					    override val collection: String = Constants.COLLECTION_CHECKER_TYPES
 | 
				
			||||||
    override val entityClass: Class<CheckerType> = CheckerType::class.java
 | 
					    override val entityClass: Class<CheckerType> = CheckerType::class.java
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory
 | 
				
			|||||||
import org.springframework.stereotype.Service
 | 
					import org.springframework.stereotype.Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
class LatestVersionFinderService(private val checkerFactory: CheckerFactory) {
 | 
					class LatestVersionFinderService(private val checkerFactory: CheckerFactory, private val versionService: VersionService) {
 | 
				
			||||||
    private val log = LoggerFactory.getLogger(LatestVersionFinderService::class.java)
 | 
					    private val log = LoggerFactory.getLogger(LatestVersionFinderService::class.java)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    suspend fun getLatestAppVersion(app: App, sources: List<Source>, checkerTypes: List<CheckerType>): String? {
 | 
					    suspend fun getLatestAppVersion(app: App, sources: List<Source>, checkerTypes: List<CheckerType>): String? {
 | 
				
			||||||
@@ -19,7 +19,7 @@ class LatestVersionFinderService(private val checkerFactory: CheckerFactory) {
 | 
				
			|||||||
        if (source != null) {
 | 
					        if (source != null) {
 | 
				
			||||||
            val checkerType: CheckerType? = checkerTypes.find { ct -> ct.id == source.checkerType }
 | 
					            val checkerType: CheckerType? = checkerTypes.find { ct -> ct.id == source.checkerType }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (checkerType != null) {
 | 
					            if (checkerType != null && app.id !=null) {
 | 
				
			||||||
                val checker: IVersionChecker = checkerFactory.createChecker(checkerType.name)
 | 
					                val checker: IVersionChecker = checkerFactory.createChecker(checkerType.name)
 | 
				
			||||||
                val paramsMap: Map<String, String> = mapOf<String, String>(
 | 
					                val paramsMap: Map<String, String> = mapOf<String, String>(
 | 
				
			||||||
                    "url" to  getUrl(app, source),
 | 
					                    "url" to  getUrl(app, source),
 | 
				
			||||||
@@ -29,7 +29,7 @@ class LatestVersionFinderService(private val checkerFactory: CheckerFactory) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                appVersion = checker.getLatestVersion(paramsMap)
 | 
					                appVersion = checker.getLatestVersion(paramsMap)
 | 
				
			||||||
                log.info("App (${app.name}, latest versión ${appVersion}")
 | 
					                log.info("App (${app.name}, latest versión ${appVersion}")
 | 
				
			||||||
 | 
					                versionService.setVersion(app.id, appVersion)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return appVersion
 | 
					        return appVersion
 | 
				
			||||||
@@ -42,7 +42,7 @@ class LatestVersionFinderService(private val checkerFactory: CheckerFactory) {
 | 
				
			|||||||
    ): Map<String, String?> {
 | 
					    ): Map<String, String?> {
 | 
				
			||||||
        val versionsMap: MutableMap<String, String?> = mutableMapOf<String, String?>()
 | 
					        val versionsMap: MutableMap<String, String?> = mutableMapOf<String, String?>()
 | 
				
			||||||
        apps.map { app ->
 | 
					        apps.map { app ->
 | 
				
			||||||
            if (app.id !== null) {
 | 
					            if (app.id !== null && app.active) {
 | 
				
			||||||
                val appLatestVersion: String? = getLatestAppVersion(app, sources, checkerTypes)
 | 
					                val appLatestVersion: String? = getLatestAppVersion(app, sources, checkerTypes)
 | 
				
			||||||
                versionsMap[app.id] = appLatestVersion
 | 
					                versionsMap[app.id] = appLatestVersion
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import kotlinx.coroutines.flow.toList
 | 
				
			|||||||
import net.xintanalabs.rssotto.db.mongodb.MongoDBClient
 | 
					import net.xintanalabs.rssotto.db.mongodb.MongoDBClient
 | 
				
			||||||
import org.springframework.beans.factory.annotation.Autowired
 | 
					import org.springframework.beans.factory.annotation.Autowired
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class ServiceBase<T: Any> @Autowired constructor(protected val mongoDBClient: MongoDBClient) {
 | 
					abstract class ServiceMongoDBBase<T: Any> @Autowired constructor(protected val mongoDBClient: MongoDBClient) {
 | 
				
			||||||
    protected abstract val collection: String
 | 
					    protected abstract val collection: String
 | 
				
			||||||
    protected abstract val entityClass: Class<T>
 | 
					    protected abstract val entityClass: Class<T>
 | 
				
			||||||
    protected val idField: String = "id"
 | 
					    protected val idField: String = "id"
 | 
				
			||||||
@@ -6,7 +6,7 @@ import net.xintanalabs.rssotto.model.Source
 | 
				
			|||||||
import org.springframework.stereotype.Service
 | 
					import org.springframework.stereotype.Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
class SourceService(mongoDBClient: MongoDBClient): ServiceBase<Source>(mongoDBClient) {
 | 
					class SourceService(mongoDBClient: MongoDBClient): ServiceMongoDBBase<Source>(mongoDBClient) {
 | 
				
			||||||
    override val collection: String = Constants.COLLECTION_SOURCES
 | 
					    override val collection: String = Constants.COLLECTION_SOURCES
 | 
				
			||||||
    override val entityClass: Class<Source> = Source::class.java
 | 
					    override val entityClass: Class<Source> = Source::class.java
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,12 @@
 | 
				
			|||||||
package net.xintanalabs.rssotto.services
 | 
					package net.xintanalabs.rssotto.services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import kotlinx.coroutines.flow.toList
 | 
					 | 
				
			||||||
import net.xintanalabs.rssotto.constants.Constants
 | 
					import net.xintanalabs.rssotto.constants.Constants
 | 
				
			||||||
import net.xintanalabs.rssotto.db.mongodb.MongoDBClient
 | 
					import net.xintanalabs.rssotto.db.mongodb.MongoDBClient
 | 
				
			||||||
import net.xintanalabs.rssotto.model.Type
 | 
					import net.xintanalabs.rssotto.model.Type
 | 
				
			||||||
import org.springframework.stereotype.Service
 | 
					import org.springframework.stereotype.Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
class TypeService(mongoDBClient: MongoDBClient) : ServiceBase<Type>(mongoDBClient) {
 | 
					class TypeService(mongoDBClient: MongoDBClient) : ServiceMongoDBBase<Type>(mongoDBClient) {
 | 
				
			||||||
    override val collection: String = Constants.COLLECTION_TYPES
 | 
					    override val collection: String = Constants.COLLECTION_TYPES
 | 
				
			||||||
    override val entityClass: Class<Type> = Type::class.java
 | 
					    override val entityClass: Class<Type> = Type::class.java
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					package net.xintanalabs.rssotto.services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.xintanalabs.rssotto.db.mongodb.MongoDBClient
 | 
				
			||||||
 | 
					import org.springframework.stereotype.Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Service
 | 
				
			||||||
 | 
					class VersionService(private val appService: AppService) {
 | 
				
			||||||
 | 
					    private val latestVersionsMap: MutableMap<String, String> = mutableMapOf()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun getVersion(appId: String): String? {
 | 
				
			||||||
 | 
					        var version = latestVersionsMap[appId]
 | 
				
			||||||
 | 
					        if (version == null) {
 | 
				
			||||||
 | 
					            version = appService.getAppById(appId)?.latestVersion
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return version
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun setVersion(appId: String, version: String) {
 | 
				
			||||||
 | 
					        latestVersionsMap[appId] = version;
 | 
				
			||||||
 | 
					        appService.updateLatestVersion(appId, version)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user