Merge pull request #6556 from osmandapp/TelegramImprovements
Telegram scan improvements
This commit is contained in:
commit
13af951629
2 changed files with 62 additions and 94 deletions
|
@ -18,7 +18,7 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
|
||||
private var bufferedMessages = emptyList<BufferMessage>()
|
||||
|
||||
private var lastLocationPoints = mutableMapOf<LocationHistoryPoint, LatLon>()
|
||||
private var lastLocationPoints = mutableListOf<LocationMessage>()
|
||||
|
||||
private val dbHelper: SQLiteHelper
|
||||
|
||||
|
@ -85,30 +85,39 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
}
|
||||
|
||||
fun addNewLocationMessage(message: TdApi.Message) {
|
||||
log.debug("addNewLocationMessage ${message.id}")
|
||||
log.debug("try addNewLocationMessage ${message.id}")
|
||||
val type = OsmandLocationUtils.getMessageType(message)
|
||||
val senderId = OsmandLocationUtils.getSenderMessageId(message)
|
||||
val content = OsmandLocationUtils.parseMessageContent(message, app.telegramHelper)
|
||||
val deviceName = if (content is OsmandLocationUtils.MessageOsmAndBotLocation) content.deviceName else ""
|
||||
val newItem = LocationHistoryPoint(OsmandLocationUtils.getSenderMessageId(message), message.chatId, type, deviceName)
|
||||
val previousMessageLatLon = lastLocationPoints[newItem]
|
||||
val locationMessage = OsmandLocationUtils.createLocationMessage(message, content, previousMessageLatLon)
|
||||
if (locationMessage != null) {
|
||||
dbHelper.addLocationMessage(locationMessage)
|
||||
lastLocationPoints[newItem] = LatLon(locationMessage.lat, locationMessage.lon)
|
||||
if (content != null) {
|
||||
val deviceName = if (content is OsmandLocationUtils.MessageOsmAndBotLocation) content.deviceName else ""
|
||||
val previousLocationMessage = lastLocationPoints.sortedBy { it.time }.firstOrNull {
|
||||
it.userId == senderId && it.chatId == message.chatId && it.deviceName == deviceName && it.type == type
|
||||
}
|
||||
if (previousLocationMessage == null || content.lastUpdated * 1000L > previousLocationMessage.time) {
|
||||
log.debug("addNewLocationMessage passed ${message.id}")
|
||||
val previousMessageLatLon = if (previousLocationMessage != null) LatLon(previousLocationMessage.lat, previousLocationMessage.lon) else null
|
||||
val locationMessage = OsmandLocationUtils.createLocationMessage(message, content, previousMessageLatLon)
|
||||
if (locationMessage != null) {
|
||||
dbHelper.addLocationMessage(locationMessage)
|
||||
lastLocationPoints.remove(previousLocationMessage)
|
||||
lastLocationPoints.add(locationMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addMyLocationMessage(loc: Location) {
|
||||
log.debug("addMyLocationMessage")
|
||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||
val newItem = LocationHistoryPoint(currentUserId, 0, LocationMessages.TYPE_MY_LOCATION, "")
|
||||
val previousMessageLatLon = lastLocationPoints[newItem]
|
||||
val distance = if (previousMessageLatLon != null) { MapUtils.getDistance(previousMessageLatLon, loc.latitude, loc.longitude) } else 0.0
|
||||
val previousLocationMessage = lastLocationPoints.sortedBy { it.time }.firstOrNull { it.userId == currentUserId && it.type == TYPE_MY_LOCATION }
|
||||
val distance = if (previousLocationMessage != null) MapUtils.getDistance(previousLocationMessage.lat, previousLocationMessage.lon, loc.latitude, loc.longitude) else 0.0
|
||||
val message = LocationMessages.LocationMessage(currentUserId, 0, loc.latitude, loc.longitude, loc.altitude,
|
||||
loc.speed.toDouble(), loc.accuracy.toDouble(), loc.bearing.toDouble(), loc.time, TYPE_MY_LOCATION, 0, distance, "")
|
||||
|
||||
dbHelper.addLocationMessage(message)
|
||||
lastLocationPoints[newItem] = LatLon(message.lat, message.lon)
|
||||
lastLocationPoints.remove(previousLocationMessage)
|
||||
lastLocationPoints.add(message)
|
||||
}
|
||||
|
||||
fun clearBufferedMessages() {
|
||||
|
@ -291,21 +300,14 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
return res
|
||||
}
|
||||
|
||||
internal fun getLastMessages(): MutableMap<LocationHistoryPoint, LatLon> {
|
||||
val res = mutableMapOf<LocationHistoryPoint, LatLon>()
|
||||
readableDatabase?.rawQuery("$TIMELINE_TABLE_SELECT_HISTORY_POINTS GROUP BY $COL_USER_ID, $COL_CHAT_ID, $COL_DEVICE_NAME, $COL_TYPE", null)?.apply {
|
||||
internal fun getLastMessages(): MutableList<LocationMessage> {
|
||||
val res = arrayListOf<LocationMessage>()
|
||||
readableDatabase?.rawQuery("$TIMELINE_TABLE_SELECT_LAST_LOCATIONS GROUP BY $COL_USER_ID, $COL_CHAT_ID, $COL_DEVICE_NAME, $COL_TYPE", null)?.apply {
|
||||
if (moveToFirst()) {
|
||||
do {
|
||||
val userId = getInt(0)
|
||||
val chatId = getLong(1)
|
||||
val lat = getDouble(2)
|
||||
val lon = getDouble(3)
|
||||
val time = getLong(4)
|
||||
val type = getInt(5)
|
||||
val deviceName = getString(6)
|
||||
val locationHistoryPoint = LocationHistoryPoint(userId, chatId, type, deviceName)
|
||||
res[locationHistoryPoint] = LatLon(lat, lon)
|
||||
log.debug("$locationHistoryPoint time: $time coords: $lat, $lon")
|
||||
val locationMessage = readLocationMessage(this@apply)
|
||||
res.add(locationMessage)
|
||||
log.debug("add last location message - $locationMessage")
|
||||
} while (moveToNext())
|
||||
}
|
||||
close()
|
||||
|
@ -403,8 +405,8 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
private const val TIMELINE_TABLE_SELECT =
|
||||
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_ID, $COL_DISTANCE_FROM_PREV, $COL_DEVICE_NAME FROM $TIMELINE_TABLE_NAME"
|
||||
|
||||
private const val TIMELINE_TABLE_SELECT_HISTORY_POINTS =
|
||||
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_TIME, $COL_TYPE, $COL_DEVICE_NAME, MAX($COL_TIME) FROM $TIMELINE_TABLE_NAME"
|
||||
private const val TIMELINE_TABLE_SELECT_LAST_LOCATIONS =
|
||||
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_ID, $COL_DISTANCE_FROM_PREV, $COL_DEVICE_NAME, MAX($COL_TIME) FROM $TIMELINE_TABLE_NAME"
|
||||
|
||||
private const val TIMELINE_TABLE_CLEAR = "DELETE FROM $TIMELINE_TABLE_NAME"
|
||||
|
||||
|
@ -505,36 +507,6 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
data class LocationHistoryPoint(
|
||||
val userId: Int,
|
||||
val chatId: Long,
|
||||
val type: Int,
|
||||
val deviceName: String
|
||||
) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other == null) {
|
||||
return false
|
||||
}
|
||||
if (other !is LocationHistoryPoint) {
|
||||
return false
|
||||
}
|
||||
val o = other as LocationHistoryPoint?
|
||||
return this.userId == o!!.userId && this.chatId == o.chatId && this.type == o.type && this.deviceName == o.deviceName
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
val prime = 31
|
||||
var result = 1
|
||||
result = prime * result + userId.hashCode()
|
||||
result = prime * result + chatId.hashCode()
|
||||
result = prime * result + type.hashCode()
|
||||
result = prime * result + deviceName.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
const val TYPE_MAP = 0
|
||||
|
|
|
@ -574,7 +574,7 @@ class TelegramHelper private constructor() {
|
|||
fun scanChatsHistory() {
|
||||
log.debug("scanChatsHistory: chatList: ${chatList.size}")
|
||||
chatList.forEach {
|
||||
scanChatHistory(it.chatId, 0, 0, 100)
|
||||
scanChatHistory(it.chatId, 0, 0, 100, mutableListOf<TdApi.Message>())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -583,9 +583,9 @@ class TelegramHelper private constructor() {
|
|||
fromMessageId: Long,
|
||||
offset: Int,
|
||||
limit: Int,
|
||||
onlyLocal: Boolean = false
|
||||
locations: MutableList<TdApi.Message>
|
||||
) {
|
||||
client?.send(TdApi.GetChatHistory(chatId, fromMessageId, offset, limit, onlyLocal)) { obj ->
|
||||
client?.send(TdApi.GetChatHistory(chatId, fromMessageId, offset, limit, false)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
|
@ -597,23 +597,35 @@ class TelegramHelper private constructor() {
|
|||
val messages = (obj as TdApi.Messages).messages
|
||||
log.debug("scanChatHistory: chatId: $chatId fromMessageId: $fromMessageId size: ${messages.size}")
|
||||
if (messages.isNotEmpty()) {
|
||||
messages.forEach {
|
||||
addNewMessage(it)
|
||||
}
|
||||
locations.addAll(messages.filter { it.isAppropriate() && !it.isOutgoing })
|
||||
val lastMessage = messages.last()
|
||||
val currentTime = System.currentTimeMillis() / 1000
|
||||
if (currentTime-Math.max(lastMessage.date, lastMessage.editDate) < MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC) {
|
||||
scanChatHistory(chatId, lastMessage.id, 0, 100)
|
||||
if (currentTime - Math.max(lastMessage.date, lastMessage.editDate) < MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC) {
|
||||
scanChatHistory(chatId, lastMessage.id, 0, 100, locations)
|
||||
log.debug("scanChatHistory searchMessageId: ${lastMessage.id}")
|
||||
} else {
|
||||
log.debug("scanChatHistory finishForChat: $chatId")
|
||||
processScannedLocationsForChat(chatId, locations)
|
||||
}
|
||||
} else {
|
||||
log.debug("scanChatHistory finishForChat: $chatId")
|
||||
processScannedLocationsForChat(chatId, locations)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processScannedLocationsForChat(chatId: Long, locations: MutableList<TdApi.Message>) {
|
||||
if (locations.isNotEmpty()) {
|
||||
locations.sortBy { message -> OsmandLocationUtils.getLastUpdatedTime(message) }
|
||||
updateLastMessage(locations.last())
|
||||
incomingMessagesListeners.forEach {
|
||||
it.onReceiveChatLocationMessages(chatId, *locations.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestUser(id: Int) {
|
||||
client?.send(TdApi.GetUser(id)) { obj ->
|
||||
when (obj.constructor) {
|
||||
|
@ -674,16 +686,7 @@ class TelegramHelper private constructor() {
|
|||
if (message.isOutgoing && !fromBot && !viaBot) {
|
||||
return
|
||||
}
|
||||
removeOldMessages(message, fromBot, viaBot)
|
||||
val oldMessage = usersLocationMessages.values.firstOrNull {
|
||||
OsmandLocationUtils.getSenderMessageId(it) == OsmandLocationUtils.getSenderMessageId(message) && it.chatId == message.chatId
|
||||
&& OsmandLocationUtils.getOsmAndBotDeviceName(it) == OsmandLocationUtils.getOsmAndBotDeviceName(message)
|
||||
}
|
||||
val hasNewerMessage = oldMessage != null && (Math.max(message.editDate, message.date) < Math.max(oldMessage.editDate, oldMessage.date))
|
||||
if (!hasNewerMessage) {
|
||||
message.content = OsmandLocationUtils.parseMessageContent(message, this)
|
||||
usersLocationMessages[message.id] = message
|
||||
}
|
||||
updateLastMessage(message)
|
||||
if (message.isOutgoing) {
|
||||
if (fromBot||viaBot) {
|
||||
outgoingMessagesListeners.forEach {
|
||||
|
@ -698,24 +701,17 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun removeOldMessages(newMessage: TdApi.Message, fromBot: Boolean, viaBot: Boolean) {
|
||||
val iterator = usersLocationMessages.entries.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val message = iterator.next().value
|
||||
if (newMessage.chatId == message.chatId) {
|
||||
val sameSender = OsmandLocationUtils.getSenderMessageId(newMessage) == OsmandLocationUtils.getSenderMessageId(message)
|
||||
val viaSameBot = newMessage.viaBotUserId == message.viaBotUserId
|
||||
if (fromBot || viaBot) {
|
||||
if ((fromBot && sameSender) || (viaBot && viaSameBot)) {
|
||||
val newDeviceName = OsmandLocationUtils.getOsmAndBotDeviceName(newMessage)
|
||||
val contDeviceName = OsmandLocationUtils.getOsmAndBotDeviceName(newMessage)
|
||||
if (newDeviceName == contDeviceName) {
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
} else if (sameSender && Math.max(newMessage.editDate, newMessage.date) >= Math.max(message.editDate, message.date)) {
|
||||
iterator.remove()
|
||||
}
|
||||
private fun updateLastMessage(message: TdApi.Message) {
|
||||
val oldMessage = usersLocationMessages.values.firstOrNull {
|
||||
OsmandLocationUtils.getSenderMessageId(it) == OsmandLocationUtils.getSenderMessageId(message)
|
||||
&& it.chatId == message.chatId && message.viaBotUserId == message.viaBotUserId
|
||||
&& OsmandLocationUtils.getOsmAndBotDeviceName(it) == OsmandLocationUtils.getOsmAndBotDeviceName(message)
|
||||
}
|
||||
if (oldMessage == null || (Math.max(message.editDate, message.date) > Math.max(oldMessage.editDate, oldMessage.date))) {
|
||||
message.content = OsmandLocationUtils.parseMessageContent(message, this)
|
||||
usersLocationMessages[message.id] = message
|
||||
oldMessage?.let {
|
||||
usersLocationMessages.remove(it.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue