mirror of
https://github.com/InsanusMokrassar/PlaguPoster.git
synced 2024-12-22 14:07:14 +00:00
add retryOnPostFailureTimes
This commit is contained in:
parent
947bd7c2c4
commit
0cc0510876
@ -11,7 +11,6 @@ import dev.inmo.tgbotapi.extensions.api.send.copyMessage
|
|||||||
import dev.inmo.tgbotapi.extensions.api.send.send
|
import dev.inmo.tgbotapi.extensions.api.send.send
|
||||||
import dev.inmo.tgbotapi.extensions.utils.*
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
|
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
|
||||||
|
|
||||||
class PostPublisher(
|
class PostPublisher(
|
||||||
@ -21,10 +20,10 @@ class PostPublisher(
|
|||||||
private val targetChatIds: List<IdChatIdentifier>,
|
private val targetChatIds: List<IdChatIdentifier>,
|
||||||
private val deleteAfterPosting: Boolean = true
|
private val deleteAfterPosting: Boolean = true
|
||||||
) {
|
) {
|
||||||
suspend fun publish(postId: PostId) {
|
suspend fun publish(postId: PostId): Boolean {
|
||||||
val messagesInfo = postsRepo.getById(postId) ?: let {
|
val messagesInfo = postsRepo.getById(postId) ?: let {
|
||||||
logger.w { "Unable to get post with id $postId for publishing" }
|
logger.w { "Unable to get post with id $postId for publishing" }
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
val sortedMessagesContents = messagesInfo.content.groupBy { it.group }.flatMap { (group, list) ->
|
val sortedMessagesContents = messagesInfo.content.groupBy { it.group }.flatMap { (group, list) ->
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
@ -35,6 +34,7 @@ class PostPublisher(
|
|||||||
listOf(list.first().order to list)
|
listOf(list.first().order to list)
|
||||||
}
|
}
|
||||||
}.sortedBy { it.first }
|
}.sortedBy { it.first }
|
||||||
|
var haveSentMessages = false
|
||||||
|
|
||||||
sortedMessagesContents.forEach { (_, contents) ->
|
sortedMessagesContents.forEach { (_, contents) ->
|
||||||
contents.singleOrNull() ?.also {
|
contents.singleOrNull() ?.also {
|
||||||
@ -44,13 +44,16 @@ class PostPublisher(
|
|||||||
}.onFailure { _ ->
|
}.onFailure { _ ->
|
||||||
runCatching {
|
runCatching {
|
||||||
bot.forwardMessage(
|
bot.forwardMessage(
|
||||||
it.chatId,
|
fromChatId = it.chatId,
|
||||||
targetChatId,
|
toChatId = cachingChatId,
|
||||||
it.messageId
|
messageId = it.messageId
|
||||||
)
|
)
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
bot.copyMessage(targetChatId, it)
|
bot.copyMessage(targetChatId, it)
|
||||||
|
haveSentMessages = true
|
||||||
}
|
}
|
||||||
|
}.onSuccess {
|
||||||
|
haveSentMessages = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@forEach
|
return@forEach
|
||||||
@ -61,12 +64,14 @@ class PostPublisher(
|
|||||||
forwardedMessage.withContentOrNull<MediaGroupPartContent>() ?: null.also { _ ->
|
forwardedMessage.withContentOrNull<MediaGroupPartContent>() ?: null.also { _ ->
|
||||||
targetChatIds.forEach { targetChatId ->
|
targetChatIds.forEach { targetChatId ->
|
||||||
bot.copyMessage(targetChatId, forwardedMessage)
|
bot.copyMessage(targetChatId, forwardedMessage)
|
||||||
|
haveSentMessages = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resultContents.singleOrNull() ?.also {
|
resultContents.singleOrNull() ?.also {
|
||||||
targetChatIds.forEach { targetChatId ->
|
targetChatIds.forEach { targetChatId ->
|
||||||
bot.copyMessage(targetChatId, it)
|
bot.copyMessage(targetChatId, it)
|
||||||
|
haveSentMessages = true
|
||||||
}
|
}
|
||||||
return@forEach
|
return@forEach
|
||||||
} ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach {
|
} ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach {
|
||||||
@ -75,6 +80,7 @@ class PostPublisher(
|
|||||||
targetChatId,
|
targetChatId,
|
||||||
it.map { it.content.toMediaGroupMemberTelegramMedia() }
|
it.map { it.content.toMediaGroupMemberTelegramMedia() }
|
||||||
)
|
)
|
||||||
|
haveSentMessages = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,5 +89,6 @@ class PostPublisher(
|
|||||||
postsRepo.deleteById(postId)
|
postsRepo.deleteById(postId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return haveSentMessages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,9 @@ import dev.inmo.plaguposter.posts.models.PostId
|
|||||||
|
|
||||||
interface Selector {
|
interface Selector {
|
||||||
suspend fun take(n: Int = 1, now: DateTime = DateTime.now(), exclude: List<PostId> = emptyList()): List<PostId>
|
suspend fun take(n: Int = 1, now: DateTime = DateTime.now(), exclude: List<PostId> = emptyList()): List<PostId>
|
||||||
|
suspend fun takeOneOrNull(now: DateTime = DateTime.now(), exclude: List<PostId> = emptyList()): PostId? = take(
|
||||||
|
n = 1,
|
||||||
|
now = now,
|
||||||
|
exclude = exclude
|
||||||
|
).firstOrNull()
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"timer_trigger": {
|
"timer_trigger": {
|
||||||
"krontab": "0 30 2/4 * *"
|
"krontab": "0 30 2/4 * *",
|
||||||
|
"retryOnPostFailureTimes": 0,
|
||||||
|
"_note": "retryOnPostFailureTimes will retry to publish one or several posts if posting has been failed"
|
||||||
},
|
},
|
||||||
"panel": {
|
"panel": {
|
||||||
"textPrefix": "Post management:",
|
"textPrefix": "Post management:",
|
||||||
|
@ -77,7 +77,7 @@ object Plugin : Plugin {
|
|||||||
|
|
||||||
return@onCommand
|
return@onCommand
|
||||||
}
|
}
|
||||||
} ?: selector ?.take(1) ?.firstOrNull()
|
} ?: selector ?.takeOneOrNull()
|
||||||
if (postId == null) {
|
if (postId == null) {
|
||||||
reply(
|
reply(
|
||||||
it,
|
it,
|
||||||
|
@ -51,7 +51,8 @@ object Plugin : Plugin {
|
|||||||
internal data class Config(
|
internal data class Config(
|
||||||
@SerialName("krontab")
|
@SerialName("krontab")
|
||||||
val krontabTemplate: KrontabTemplate,
|
val krontabTemplate: KrontabTemplate,
|
||||||
val dateTimeFormat: String = "HH:mm:ss, dd.MM.yyyy"
|
val dateTimeFormat: String = "HH:mm:ss, dd.MM.yyyy",
|
||||||
|
val retryOnPostFailureTimes: Int = 0
|
||||||
) {
|
) {
|
||||||
@Transient
|
@Transient
|
||||||
val krontab by lazy {
|
val krontab by lazy {
|
||||||
@ -88,13 +89,27 @@ object Plugin : Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val krontab = koin.get<Config>().krontab
|
val krontab = koin.get<Config>().krontab
|
||||||
|
val retryOnPostFailureTimes = koin.get<Config>().retryOnPostFailureTimes
|
||||||
val dateTimeFormat = koin.get<Config>().format
|
val dateTimeFormat = koin.get<Config>().format
|
||||||
krontab.asFlowWithDelays().subscribeSafelyWithoutExceptions(this) { dateTime ->
|
krontab.asFlowWithDelays().subscribeSafelyWithoutExceptions(this) { dateTime ->
|
||||||
selector.take(now = dateTime).forEach { postId ->
|
var leftRetries = retryOnPostFailureTimes
|
||||||
|
do {
|
||||||
|
val success = runCatching {
|
||||||
|
selector.takeOneOrNull(now = dateTime) ?.let { postId ->
|
||||||
if (filters.all { it.check(postId, dateTime) }) {
|
if (filters.all { it.check(postId, dateTime) }) {
|
||||||
publisher.publish(postId)
|
publisher.publish(postId)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
} ?: false
|
||||||
|
}.getOrElse {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
if (success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
leftRetries--;
|
||||||
|
} while (leftRetries > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun buildPage(pagination: Pagination = FirstPagePagination(size = pageCallbackDataQuerySize)): InlineKeyboardMarkup {
|
suspend fun buildPage(pagination: Pagination = FirstPagePagination(size = pageCallbackDataQuerySize)): InlineKeyboardMarkup {
|
||||||
@ -113,7 +128,7 @@ object Plugin : Plugin {
|
|||||||
|
|
||||||
val selected = mutableListOf<PostId>()
|
val selected = mutableListOf<PostId>()
|
||||||
krontab.asFlowWithoutDelays().take(pagination.lastIndexExclusive).collectIndexed { i, dateTime ->
|
krontab.asFlowWithoutDelays().take(pagination.lastIndexExclusive).collectIndexed { i, dateTime ->
|
||||||
val postId = selector.take(now = dateTime, exclude = selected).firstOrNull() ?.also { postId ->
|
val postId = selector.takeOneOrNull(now = dateTime, exclude = selected) ?.also { postId ->
|
||||||
if (filters.all { it.check(postId, dateTime) }) {
|
if (filters.all { it.check(postId, dateTime) }) {
|
||||||
selected.add(postId)
|
selected.add(postId)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user