mirror of
https://github.com/n08i40k/polytechnic-android.git
synced 2025-12-06 09:47:48 +03:00
Релиз 1.2
Теперь сайт политеха не сможет забанить сервер за пинг его каждые 5 секунд.
This commit is contained in:
6
.idea/misc.xml
generated
6
.idea/misc.xml
generated
@@ -1,5 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
|
||||
@@ -32,8 +32,8 @@ android {
|
||||
applicationId = "ru.n08i40k.polytechnic.next"
|
||||
minSdk = 26
|
||||
targetSdk = 35
|
||||
versionCode = 2
|
||||
versionName = "1.1"
|
||||
versionCode = 3
|
||||
versionName = "1.2"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package ru.n08i40k.polytechnic.next.data.schedule.impl
|
||||
|
||||
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.StringRequest
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
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.schedule.ScheduleRepository
|
||||
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.ScheduleGetRequestData
|
||||
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 java.util.logging.Logger
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
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> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val logger = Logger.getLogger("RemoteScheduleRepository")
|
||||
|
||||
val groupName = runBlocking {
|
||||
context.settingsDataStore.data.map { settings -> settings.group }.first()
|
||||
}
|
||||
@@ -25,16 +81,49 @@ class RemoteScheduleRepository(private val context: Context) : ScheduleRepositor
|
||||
if (groupName.isEmpty())
|
||||
return@withContext MyResult.Failure(IllegalArgumentException("No group name provided!"))
|
||||
|
||||
val responseFuture = RequestFuture.newFuture<ScheduleGetResponse>()
|
||||
val firstPassFuture = RequestFuture.newFuture<ScheduleGetResponse>()
|
||||
ScheduleGetRequest(
|
||||
ScheduleGetRequestData(groupName),
|
||||
context,
|
||||
responseFuture,
|
||||
responseFuture
|
||||
firstPassFuture,
|
||||
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()
|
||||
|
||||
try {
|
||||
MyResult.Success(responseFuture.get().group)
|
||||
MyResult.Success(secondPassFuture.get().group)
|
||||
} catch (exception: Exception) {
|
||||
MyResult.Failure(exception)
|
||||
}
|
||||
|
||||
@@ -8,5 +8,6 @@ data class ScheduleGetResponse(
|
||||
val updatedAt: String,
|
||||
val group: Group,
|
||||
val etag: String,
|
||||
val lastChangedDays: ArrayList<Int>
|
||||
val lastChangedDays: ArrayList<Int>,
|
||||
val updateRequired: Boolean
|
||||
)
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package ru.n08i40k.polytechnic.next.network.data.schedule
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ScheduleUpdateRequestData(val mainPage: String)
|
||||
Reference in New Issue
Block a user