parent
df58002041
commit
25ef38db3a
@ -0,0 +1,163 @@
|
||||
package com.example.service
|
||||
|
||||
import android.util.Log
|
||||
import com.example.action.BaseAction
|
||||
import com.example.action.Next
|
||||
import com.example.logger.LogUtils
|
||||
import com.example.pin.NotificationMessage
|
||||
import com.example.report.ActionExec
|
||||
import com.example.task.TaskConfig
|
||||
import com.example.utils.toJsonString
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
class PinService(
|
||||
private val action: BaseAction.PinAction,
|
||||
override val taskConfig: TaskConfig
|
||||
) : BaseService(taskConfig) {
|
||||
|
||||
override suspend fun execute(onFinish: (List<ActionExec>) -> Unit) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val actionExecList: MutableList<ActionExec> = mutableListOf()
|
||||
var currentStep = taskConfig.currentStep
|
||||
kotlin.runCatching {
|
||||
val start = System.currentTimeMillis()
|
||||
var respCode = 200
|
||||
var cost = 0L
|
||||
val messageLog: MutableList<NotificationMessage> = mutableListOf()
|
||||
val nextList = action.next
|
||||
LogUtils.info("next list: ${nextList.map { it.regexp + ", " + it.contain }}")
|
||||
withTimeoutOrNull(action.delay.toDuration(DurationUnit.SECONDS)) {
|
||||
while (isActive) {
|
||||
val notificationCache = taskConfig.notificationCache
|
||||
if (nextList.isNotEmpty() && notificationCache.isNotEmpty()) {
|
||||
val notificationMessages =
|
||||
haveNextCatchTargetMessage(notificationCache, nextList)
|
||||
if (notificationMessages.isNotEmpty()) {
|
||||
LogUtils.info("catch target message...")
|
||||
messageLog.addAll(notificationMessages)
|
||||
break
|
||||
}
|
||||
}
|
||||
cost = System.currentTimeMillis() - start
|
||||
LogUtils.info("waiting for target message... ${action.delay}, escape: ${cost / 1000f}")
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
cost = System.currentTimeMillis() - start
|
||||
LogUtils.info("waiting for target message... finish ${cost/1000f}")
|
||||
if (messageLog.isNotEmpty()) {
|
||||
val nextStep =
|
||||
nextList.getNextStepIndex(
|
||||
messageLog.toJsonString(),
|
||||
currentStep
|
||||
)
|
||||
taskConfig.currentStep = nextStep
|
||||
} else {
|
||||
if (nextList.isNotEmpty()) {
|
||||
taskConfig.currentStep = Int.MAX_VALUE
|
||||
respCode = ERROR_CODE_PIN_ACTION_TIMEOUT
|
||||
if(taskConfig.notificationCache.isNotEmpty()) {
|
||||
messageLog += taskConfig.notificationCache.last()
|
||||
}
|
||||
} else {
|
||||
taskConfig.currentStep = ++currentStep
|
||||
messageLog += taskConfig.notificationCache
|
||||
}
|
||||
}
|
||||
if (taskConfig.currentStep != Int.MAX_VALUE && messageLog.isNotEmpty()) {
|
||||
val responseBody = messageLog.toJsonString()
|
||||
extractBodyVariableToCache(action, responseBody, responseBody.toByteArray())
|
||||
}
|
||||
|
||||
val actionExec = genActionExec(messageLog, currentStep, respCode, cost)
|
||||
actionExecList += actionExec
|
||||
}.onFailure {
|
||||
LogUtils.error(it)
|
||||
val actionExec = genExceptionActionExec(
|
||||
action,
|
||||
ERROR_CODE_PIN_ACTION_EXEC_FAILED,
|
||||
Log.getStackTraceString(it)
|
||||
)
|
||||
actionExecList += actionExec
|
||||
if (action.skipError) {
|
||||
taskConfig.currentStep = ++currentStep
|
||||
} else {
|
||||
taskConfig.currentStep = Int.MAX_VALUE
|
||||
}
|
||||
}
|
||||
onFinish(actionExecList)
|
||||
}
|
||||
}
|
||||
|
||||
private fun genActionExec(
|
||||
messageLog: MutableList<NotificationMessage>,
|
||||
currentStep: Int,
|
||||
respCode: Int,
|
||||
cost: Long
|
||||
): ActionExec {
|
||||
val actionExec = ActionExec().apply {
|
||||
this.step = currentStep
|
||||
this.index = 1
|
||||
this.respCode = respCode
|
||||
this.cost = cost
|
||||
this.time = System.currentTimeMillis()
|
||||
if (messageLog.isNotEmpty()) {
|
||||
this.url = messageLog.first().app
|
||||
this.respData = messageLog.toJsonString()
|
||||
}
|
||||
}
|
||||
return actionExec
|
||||
}
|
||||
|
||||
private fun haveNextCatchTargetMessage(
|
||||
notificationCache: List<NotificationMessage>,
|
||||
nextList: List<Next>
|
||||
): List<NotificationMessage> {
|
||||
var result: List<NotificationMessage> = mutableListOf()
|
||||
var targetMessage: NotificationMessage? = null
|
||||
LogUtils.info("message size: ${notificationCache.size}")
|
||||
for (notify in notificationCache) {
|
||||
LogUtils.info("notify: ${notify.content}")
|
||||
for (next in nextList) {
|
||||
if (next.step <= 0) continue
|
||||
LogUtils.info("next:$next")
|
||||
val contain = next.contain
|
||||
if (contain.isNotBlank() && (notify.from.contains(contain) ||
|
||||
notify.content.contains(contain))
|
||||
) {
|
||||
targetMessage = notify
|
||||
break
|
||||
}
|
||||
|
||||
if (next.regexp.isNotBlank()) {
|
||||
val pattern = next.regexp.toRegex()
|
||||
var matcher = pattern.matches(notify.from)
|
||||
if (matcher) {
|
||||
targetMessage = notify
|
||||
break
|
||||
}
|
||||
|
||||
matcher = pattern.matches(notify.content)
|
||||
if (matcher) {
|
||||
targetMessage = notify
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetMessage != null) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (targetMessage != null) {
|
||||
result = notificationCache.filter { targetMessage.from == it.from }.toList()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue