Skip to content

Commit

Permalink
Приватные видосы
Browse files Browse the repository at this point in the history
  • Loading branch information
Spliterash committed Oct 8, 2024
1 parent ceecc60 commit bb78884
Show file tree
Hide file tree
Showing 33 changed files with 258 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class VkConfiguration(
@Bean
@GroupUser
fun groupActor(
@Value("\${vk-unlocker.group.id}") id: Int,
@Value("\${vk-unlocker.group.id}") id: Long,
@Value("\${vk-unlocker.group.token}") token: String
): VkApi = context.createBean(VkApiImpl::class.java, Actor(id, token))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.spliterash.vkVideoUnlocker.common.exceptions

interface AlwaysNotifyException
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import ru.spliterash.vkVideoUnlocker.vk.api.VkApi
class WorkUserGroupService(
@DownloadUser private val user: VkApi
) {
private val groups = hashMapOf<Int, GroupInfo>()
private val groups = hashMapOf<Long, GroupInfo>()
private val lock = Mutex()

/**
Expand All @@ -28,7 +28,7 @@ class WorkUserGroupService(
* @return Статус группы
*/
@Throws(VideoGroupPrivateException::class, VideoGroupRequestSendException::class)
suspend fun joinGroup(groupId: Int): GroupStatus {
suspend fun joinGroup(groupId: Long): GroupStatus {
val groupInfo = lock.withLock { groups[groupId] }
if (groupInfo != null) {
val groupIsOpen = groupInfo.groupStatus == GroupStatus.PUBLIC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import ru.spliterash.vkVideoUnlocker.group.dto.GroupInfo
import ru.spliterash.vkVideoUnlocker.group.vkModels.LongPollServerResponse

interface Groups {
suspend fun status(groupId: Int): GroupInfo
suspend fun join(groupId: Int)
suspend fun status(groupId: Long): GroupInfo
suspend fun join(groupId: Long)

suspend fun getLongPollServer(): LongPollServerResponse

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import ru.spliterash.vkVideoUnlocker.group.dto.GroupStatus
import ru.spliterash.vkVideoUnlocker.group.dto.MemberStatus
import ru.spliterash.vkVideoUnlocker.group.vkModels.LongPollServerResponse
import ru.spliterash.vkVideoUnlocker.group.vkModels.VkGroupGetByIdResponse
import ru.spliterash.vkVideoUnlocker.vk.VkConst
import ru.spliterash.vkVideoUnlocker.vk.VkHelper
import ru.spliterash.vkVideoUnlocker.vk.actor.types.Actor
import ru.spliterash.vkVideoUnlocker.vk.VkConst

@Prototype
class GroupsImpl(
Expand All @@ -27,7 +27,7 @@ class GroupsImpl(
private val log = LoggerFactory.getLogger(GroupsImpl::class.java)
}

override suspend fun status(groupId: Int): GroupInfo {
override suspend fun status(groupId: Long): GroupInfo {
val request = VkConst.requestBuilder()
.url(
VkConst.urlBuilder("groups.getById") // Hidden method, taken from mobile app
Expand Down Expand Up @@ -62,7 +62,7 @@ class GroupsImpl(
)
}

override suspend fun join(groupId: Int) {
override suspend fun join(groupId: Long) {
val request = VkConst.requestBuilder()
.url(
VkConst.urlBuilder("groups.join")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ru.spliterash.vkVideoUnlocker.longpoll.message
import com.fasterxml.jackson.annotation.JsonProperty

data class RootMessage(
@JsonProperty("id") val id: String,
@JsonProperty("attachments") override val attachments: List<Attachment>,
@JsonProperty("conversation_message_id") val conversationMessageId: Long,
@JsonProperty("fwd_messages") override val fwdMessages: List<FwdMessage> = listOf(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import com.fasterxml.jackson.annotation.JsonProperty
import ru.spliterash.vkVideoUnlocker.longpoll.message.Attachment

data class Wall(
@JsonProperty("id")
val id: Long,
@JsonProperty("owner_id")
val ownerId: Long,
@JsonProperty("attachments")
val attachments: List<Attachment> = listOf(),
@JsonProperty("copy_history")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package ru.spliterash.vkVideoUnlocker.message.api

import ru.spliterash.vkVideoUnlocker.longpoll.message.RootMessage

interface Messages {
suspend fun messageById(
groupId: Long,
messageId: String
): RootMessage

suspend fun sendMessage(
peerId: Long,
message: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import io.micronaut.context.annotation.Parameter
import io.micronaut.context.annotation.Prototype
import okhttp3.OkHttpClient
import ru.spliterash.vkVideoUnlocker.common.okHttp.executeAsync
import ru.spliterash.vkVideoUnlocker.longpoll.message.RootMessage
import ru.spliterash.vkVideoUnlocker.message.vkModels.request.Forward
import ru.spliterash.vkVideoUnlocker.message.vkModels.response.MessageSendResponse
import ru.spliterash.vkVideoUnlocker.video.api.VideosImpl
import ru.spliterash.vkVideoUnlocker.vk.VkConst
import ru.spliterash.vkVideoUnlocker.vk.VkHelper
import ru.spliterash.vkVideoUnlocker.vk.vkModels.VkItemsResponse

@Prototype
class MessagesImpl(
Expand All @@ -23,6 +26,23 @@ class MessagesImpl(
) + "..." else
this

override suspend fun messageById(groupId: Long, messageId: String): RootMessage {
val response = VkConst
.requestBuilder()
.header("user-agent", VideosImpl.USER_AGENT)
.url(
VkConst.urlBuilder("messages.getById")
.addQueryParameter("group_id", groupId.toString())
.addQueryParameter("message_ids", messageId)
.build()
)
.build()
.executeAsync(client)

val result = vkHelper.readResponse(response, object : TypeReference<VkItemsResponse<RootMessage>>() {})
return result.items.first()
}


override suspend fun sendMessage(peerId: Long, message: String?, replyTo: Long?, attachments: String?): Long {
val response = VkConst
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ru.spliterash.vkVideoUnlocker.message.utils

import jakarta.inject.Singleton
import ru.spliterash.vkVideoUnlocker.longpoll.message.ReplyMessage
import ru.spliterash.vkVideoUnlocker.longpoll.message.RootMessage
import ru.spliterash.vkVideoUnlocker.longpoll.message.attachments.AttachmentContainer
import ru.spliterash.vkVideoUnlocker.longpoll.message.hasPing
import ru.spliterash.vkVideoUnlocker.longpoll.message.isPersonalChat
import ru.spliterash.vkVideoUnlocker.vk.MessageScanner
import ru.spliterash.vkVideoUnlocker.vk.actor.GroupUser
import ru.spliterash.vkVideoUnlocker.vk.api.VkApi
import java.util.*
import java.util.function.Predicate

@Singleton
class MessageContentScanner(
@GroupUser private val groupUser: VkApi,
private val messageScanner: MessageScanner,
) {
fun findContent(root: RootMessage): MessageScanner.ScanResult? {
val containerPredicate: Predicate<AttachmentContainer> =
if (root.isPersonalChat() || root.hasPing(groupUser))
Predicate { true }
else
Predicate { it !is ReplyMessage }

val init = LinkedList<AttachmentContainer>()
init += root
return messageScanner.scanForAttachment(
init,
listOf(
MessageScanner.Checker { it.video },
MessageScanner.Checker { it.story },
),
containerPredicate
)
}
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,26 @@
package ru.spliterash.vkVideoUnlocker.message.utils

import jakarta.inject.Singleton
import ru.spliterash.vkVideoUnlocker.longpoll.message.ReplyMessage
import ru.spliterash.vkVideoUnlocker.longpoll.message.RootMessage
import ru.spliterash.vkVideoUnlocker.longpoll.message.attachments.AttachmentContainer
import ru.spliterash.vkVideoUnlocker.longpoll.message.hasPing
import ru.spliterash.vkVideoUnlocker.longpoll.message.isPersonalChat
import ru.spliterash.vkVideoUnlocker.story.vkModels.VkStory
import ru.spliterash.vkVideoUnlocker.video.holder.VideoContentHolder
import ru.spliterash.vkVideoUnlocker.video.service.VideoService
import ru.spliterash.vkVideoUnlocker.video.vkModels.VkVideo
import ru.spliterash.vkVideoUnlocker.vk.MessageScanner
import ru.spliterash.vkVideoUnlocker.vk.actor.GroupUser
import ru.spliterash.vkVideoUnlocker.vk.api.VkApi
import ru.spliterash.vkVideoUnlocker.wall.vkModels.WallPost
import java.util.function.Predicate
import java.util.regex.Pattern

@Singleton
class MessageUtils(
@GroupUser private val groupUser: VkApi,
private val messageScanner: MessageScanner,
private val messageContentScanner: MessageContentScanner,
private val videoService: VideoService,
) {
private val vkUrlPattern = Pattern.compile("(?:https?://)?vk\\.com/(?<attachment>(?:video|wall|story)-?\\d+_\\d+)")
suspend fun scanForVideoContent(root: RootMessage): VideoContentHolder? {
val containerPredicate: Predicate<AttachmentContainer> =
if (root.isPersonalChat() || root.hasPing(groupUser))
Predicate { true }
else
Predicate { it !is ReplyMessage }

val attachmentContent = messageScanner.scanForAttachment(
root,
listOf(
MessageScanner.Checker { it.video },
MessageScanner.Checker { it.story },
),
containerPredicate
)
if (attachmentContent != null) {
suspend fun scanForVideoContent(root: RootMessage): VideoContentHolder? {
val scanResult = messageContentScanner.findContent(root)
if (scanResult != null) {
val (attachmentContent, chain) = scanResult
return when (attachmentContent) {
is VkVideo -> videoService.wrap(attachmentContent)
is VkVideo -> videoService.wrap(attachmentContent, chain)
is VkStory -> videoService.wrap(attachmentContent)
else -> throw IllegalArgumentException("Impossible exception")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import jakarta.inject.Singleton
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import ru.spliterash.vkVideoUnlocker.common.exceptions.AlwaysNotifyException
import ru.spliterash.vkVideoUnlocker.common.exceptions.VkUnlockerException
import ru.spliterash.vkVideoUnlocker.longpoll.message.RootMessage
import ru.spliterash.vkVideoUnlocker.longpoll.message.hasPing
Expand All @@ -13,6 +14,7 @@ import ru.spliterash.vkVideoUnlocker.message.editableMessage.EditableMessage
import ru.spliterash.vkVideoUnlocker.message.utils.MessageUtils
import ru.spliterash.vkVideoUnlocker.messageChain.MessageHandler
import ru.spliterash.vkVideoUnlocker.video.DownloadUrlSupplier
import ru.spliterash.vkVideoUnlocker.video.exceptions.NoSenseReuploadUserVideos
import ru.spliterash.vkVideoUnlocker.video.exceptions.PrivateVideoDisabledException
import ru.spliterash.vkVideoUnlocker.video.exceptions.VideoTooLongException
import ru.spliterash.vkVideoUnlocker.video.service.VideoReUploadService
Expand All @@ -33,6 +35,11 @@ class DefaultVideoChain(
handleException(ex, message)
return@coroutineScope true
} ?: return@coroutineScope false
if (video.ownerId > 0) {
handleException(NoSenseReuploadUserVideos(), message)
return@coroutineScope true
}


val notifyJob = launch {
delay(3000)
Expand Down Expand Up @@ -75,7 +82,7 @@ class DefaultVideoChain(
}

private fun handleException(ex: VkUnlockerException, message: RootMessage) {
if (message.isPersonalChat())
if (message.isPersonalChat() || ex is AlwaysNotifyException)
throw ex
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import ru.spliterash.vkVideoUnlocker.message.editableMessage.EditableMessage
import ru.spliterash.vkVideoUnlocker.message.utils.MessageUtils
import ru.spliterash.vkVideoUnlocker.messageChain.ActivationMessageHandler
import ru.spliterash.vkVideoUnlocker.video.DownloadUrlSupplier
import ru.spliterash.vkVideoUnlocker.video.holder.VideoHolder
import ru.spliterash.vkVideoUnlocker.video.vkModels.fullId

@Singleton
class DownloadVideoChain(
Expand All @@ -24,7 +26,11 @@ class DownloadVideoChain(
if (videoHolder == null) {
editableMessage.sendOrUpdate("Прикрепи видео к сообщению, ну или перешли его как обычно, чтобы я знал что тебе нужно")
} else {
val url = downloadUrlSupplier.downloadUrl(videoHolder.attachmentId)
val baseUrl = if (videoHolder is VideoHolder) {
"video" + videoHolder.fullVideo().video.fullId()
} else videoHolder.attachmentId

val url = downloadUrlSupplier.downloadUrl(baseUrl)
editableMessage.sendOrUpdate("Скачать: $url")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface Videos {
* Выгрузить видос
*/
suspend fun upload(
groupId: Int,
groupId: Long,
name: String,
private: Boolean,
accessor: VideoAccessor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.fasterxml.jackson.module.kotlin.readValue
import io.micronaut.context.annotation.Parameter
import io.micronaut.context.annotation.Prototype
import okhttp3.OkHttpClient
import org.apache.commons.io.IOUtils
import ru.spliterash.vkVideoUnlocker.common.VkUploaderService
import ru.spliterash.vkVideoUnlocker.common.okHttp.executeAsync
import ru.spliterash.vkVideoUnlocker.common.vkModels.VkUploadUrlResponse
Expand All @@ -19,7 +18,6 @@ import ru.spliterash.vkVideoUnlocker.vk.VkConst
import ru.spliterash.vkVideoUnlocker.vk.VkHelper
import ru.spliterash.vkVideoUnlocker.vk.readResponse
import ru.spliterash.vkVideoUnlocker.vk.vkModels.VkItemsResponse
import java.io.FileOutputStream

@Prototype
class VideosImpl(
Expand Down Expand Up @@ -55,7 +53,7 @@ class VideosImpl(
}

override suspend fun upload(
groupId: Int,
groupId: Long,
name: String,
private: Boolean,
accessor: VideoAccessor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,19 @@ class VideoController(
.expireAfterWrite(30, TimeUnit.MINUTES)
.build<String, Deferred<AdvancedVideoAccessor>> {
scope.async {
load(it).toAccessor()
try {
load(it).toAccessor()
} catch (ex: Exception) {
invalidate(it)
throw ex
}
}
}

private fun invalidate(id: String) {
cache.invalidate(id)
}

private suspend fun load(attachmentId: String): FullVideo {
val holder = videoService.wrapAttachmentId(attachmentId)

Expand Down Expand Up @@ -85,7 +94,7 @@ class VideoController(
@Header("Range", defaultValue = "") rangeHeader: String?,
@Header("X-Forwarded-For", defaultValue = "idk") ipHeader: String?
): HttpResponse<StreamedFile> {
val accessor = cache.get(attachmentId).await()
val accessor = cache.get(attachmentId.removeSuffix(".mp4")).await()
val qualityInt = try {
quality.toInt()
} catch (ex: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.spliterash.vkVideoUnlocker.video.exceptions

import ru.spliterash.vkVideoUnlocker.common.exceptions.AlwaysNotifyException
import ru.spliterash.vkVideoUnlocker.common.exceptions.VkUnlockerException

class ContentNotFoundException : VkUnlockerException(),AlwaysNotifyException {
override fun messageForUser(): String {
return "Я не знаю каким образом, но при получении сообщения от пользователя, содержимое отличается"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.spliterash.vkVideoUnlocker.video.exceptions

import ru.spliterash.vkVideoUnlocker.common.exceptions.VkUnlockerException

class NoSenseReuploadUserVideos : VkUnlockerException() {
override fun messageForUser(): String {
return "Мне нет смысла перезаливать пользовательские видео"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.spliterash.vkVideoUnlocker.video.exceptions

import ru.spliterash.vkVideoUnlocker.common.exceptions.AlwaysNotifyException
import ru.spliterash.vkVideoUnlocker.common.exceptions.VkUnlockerException

class NoSourceException : VkUnlockerException(), AlwaysNotifyException {
override fun messageForUser() =
"Перешли видео в личные сообщения сообщества. Из за ограничений API я не могу сделать это в беседе"
}
Loading

0 comments on commit bb78884

Please sign in to comment.