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"?>
|
<?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" />
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
@@ -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