Релиз 1.2

Теперь сайт политеха не сможет забанить сервер за пинг его каждые 5 секунд.
This commit is contained in:
2024-09-16 15:10:27 +04:00
parent ee7c4b06a1
commit c98d34bd98
6 changed files with 131 additions and 7 deletions

6
.idea/misc.xml generated
View File

@@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="EntryPointsManager">
<list size="2">
<item index="0" class="java.lang.String" itemvalue="dagger.Module" />
<item index="1" class="java.lang.String" itemvalue="dagger.Provides" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />

View File

@@ -32,8 +32,8 @@ android {
applicationId = "ru.n08i40k.polytechnic.next" applicationId = "ru.n08i40k.polytechnic.next"
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 35
versionCode = 2 versionCode = 3
versionName = "1.1" versionName = "1.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {

View File

@@ -1,7 +1,10 @@
package ru.n08i40k.polytechnic.next.data.schedule.impl package ru.n08i40k.polytechnic.next.data.schedule.impl
import android.content.Context import android.content.Context
import com.android.volley.Request
import com.android.volley.ServerError
import com.android.volley.toolbox.RequestFuture import com.android.volley.toolbox.RequestFuture
import com.android.volley.toolbox.StringRequest
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@@ -10,14 +13,67 @@ import kotlinx.coroutines.withContext
import ru.n08i40k.polytechnic.next.data.MyResult import ru.n08i40k.polytechnic.next.data.MyResult
import ru.n08i40k.polytechnic.next.data.schedule.ScheduleRepository import ru.n08i40k.polytechnic.next.data.schedule.ScheduleRepository
import ru.n08i40k.polytechnic.next.model.Group import ru.n08i40k.polytechnic.next.model.Group
import ru.n08i40k.polytechnic.next.network.NetworkConnection
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequest import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequest
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequestData import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequestData
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetResponse import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetResponse
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleUpdateRequest
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleUpdateRequestData
import ru.n08i40k.polytechnic.next.settings.settingsDataStore import ru.n08i40k.polytechnic.next.settings.settingsDataStore
import java.util.logging.Logger
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
class RemoteScheduleRepository(private val context: Context) : ScheduleRepository { class RemoteScheduleRepository(private val context: Context) : ScheduleRepository {
@OptIn(ExperimentalEncodingApi::class)
suspend fun getMainPage(): MyResult<String> {
return withContext(Dispatchers.IO) {
val mainPageFuture = RequestFuture.newFuture<String>()
val request = StringRequest(
Request.Method.GET,
"https://politehnikum-eng.ru/index/raspisanie_zanjatij/0-409",
mainPageFuture,
mainPageFuture
)
NetworkConnection.getInstance(context).addToRequestQueue(request)
try {
val encodedMainPage =
Base64.Default.encode(mainPageFuture.get().encodeToByteArray())
MyResult.Success(encodedMainPage)
} catch (exception: Exception) {
MyResult.Failure(exception)
}
}
}
suspend fun updateMainPage(): MyResult<Nothing> {
return withContext(Dispatchers.IO) {
val mainPage = getMainPage()
if (mainPage is MyResult.Failure)
return@withContext mainPage
val updateFuture = RequestFuture.newFuture<Nothing>()
ScheduleUpdateRequest(
ScheduleUpdateRequestData((mainPage as MyResult.Success<String>).data),
context,
updateFuture,
updateFuture
).send()
try {
MyResult.Success(updateFuture.get())
} catch (exception: Exception) {
MyResult.Failure(exception)
}
}
}
override suspend fun getGroup(): MyResult<Group> { override suspend fun getGroup(): MyResult<Group> {
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
val logger = Logger.getLogger("RemoteScheduleRepository")
val groupName = runBlocking { val groupName = runBlocking {
context.settingsDataStore.data.map { settings -> settings.group }.first() context.settingsDataStore.data.map { settings -> settings.group }.first()
} }
@@ -25,16 +81,49 @@ class RemoteScheduleRepository(private val context: Context) : ScheduleRepositor
if (groupName.isEmpty()) if (groupName.isEmpty())
return@withContext MyResult.Failure(IllegalArgumentException("No group name provided!")) return@withContext MyResult.Failure(IllegalArgumentException("No group name provided!"))
val responseFuture = RequestFuture.newFuture<ScheduleGetResponse>() val firstPassFuture = RequestFuture.newFuture<ScheduleGetResponse>()
ScheduleGetRequest( ScheduleGetRequest(
ScheduleGetRequestData(groupName), ScheduleGetRequestData(groupName),
context, context,
responseFuture, firstPassFuture,
responseFuture firstPassFuture
).send()
var firstPassResponse: ScheduleGetResponse? = null
try {
firstPassResponse = firstPassFuture.get()
if (!firstPassResponse.updateRequired) {
logger.info("Successfully get group schedule!")
return@withContext MyResult.Success(firstPassFuture.get().group)
}
logger.info("Successfully get group schedule, but it needs to update!")
} catch (exception: Exception) {
if (exception.cause !is ServerError)
return@withContext MyResult.Failure(exception)
logger.info("Can't get group schedule, because it needs to first update!")
}
val updateResult = updateMainPage()
if (updateResult is MyResult.Failure) {
logger.info("Can't update site main page!")
if (firstPassResponse != null)
return@withContext MyResult.Success(firstPassResponse.group)
return@withContext updateResult
}
logger.info("Site main page successfully updated!")
val secondPassFuture = RequestFuture.newFuture<ScheduleGetResponse>()
ScheduleGetRequest(
ScheduleGetRequestData(groupName),
context,
secondPassFuture,
secondPassFuture
).send() ).send()
try { try {
MyResult.Success(responseFuture.get().group) MyResult.Success(secondPassFuture.get().group)
} catch (exception: Exception) { } catch (exception: Exception) {
MyResult.Failure(exception) MyResult.Failure(exception)
} }

View File

@@ -8,5 +8,6 @@ data class ScheduleGetResponse(
val updatedAt: String, val updatedAt: String,
val group: Group, val group: Group,
val etag: String, val etag: String,
val lastChangedDays: ArrayList<Int> val lastChangedDays: ArrayList<Int>,
val updateRequired: Boolean
) )

View File

@@ -0,0 +1,22 @@
package ru.n08i40k.polytechnic.next.network.data.schedule
import android.content.Context
import com.android.volley.Response
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import ru.n08i40k.polytechnic.next.network.data.AuthorizedRequest
class ScheduleUpdateRequest(
private val data: ScheduleUpdateRequestData,
context: Context,
listener: Response.Listener<Nothing>,
errorListener: Response.ErrorListener? = null
) : AuthorizedRequest(
context, Method.POST, "schedule/update-site-main-page", Response.Listener<String> {
listener.onResponse(null)
}, errorListener
) {
override fun getBody(): ByteArray {
return Json.encodeToString(data).toByteArray()
}
}

View File

@@ -0,0 +1,6 @@
package ru.n08i40k.polytechnic.next.network.data.schedule
import kotlinx.serialization.Serializable
@Serializable
data class ScheduleUpdateRequestData(val mainPage: String)