Add tracker for lost messages

This commit is contained in:
Fierelier 2020-11-24 15:41:05 +01:00
parent 5d857a3cd4
commit 04506b3601
2 changed files with 107 additions and 6 deletions

View File

@ -4,6 +4,16 @@ historyFetch = 20
; How many messages can be collectively displayed in a conversation?
maxMessagesListed = 100
[messageTracking]
; Save last message activity time into files? This is used to retrieve messages after experiencing a disconnect or similar. false = disabled, true = enabled
trackMessages = true
; Recheck messages on (re)connect? This will loop through every channel after login, or reconnect.
recheckMessages = true
; Recheck messages in an interval? This will loop through every channel every x seconds, trying to retrieve messages that have been made after the last tracked time. Requires trackMessages to be true. 0 = disabled
recheckMessagesTimer = 300
; Retrieve new messages with paranoia? This will try to retrieve messages beyond the message that arrived, until the last message that was actually tracked. This will result in 2 messages always being processed, when a new message comes in. If more than 2 messages are found, they are pushed. Requires trackMessages to be true. false = disabled, true = enabled
paranoidMessages = true
[style]
; Qt's base style. Fusion, Breeze, Windows, etc... default = system default - Using anything else than default could override your font and color choices in some instances. Try the Windows theme if some of your colors do not apply.
baseStyle = default

View File

@ -28,6 +28,7 @@ import threading
import asyncio
import logging
import configparser
import datetime
distro = "Discord but fast"
version = (0,1,0)
versionString = ".".join(map(str,version))
@ -446,7 +447,7 @@ class guiChannel:
def addMessage(self, message):
global config
while len(self.messages) >= maxMessages: del messages[0]
while len(self.messages) >= int(config["performance"]["maxMessagesListed"]): del messages[0]
self.messages.append(message)
self.messageLog.set({})
for message in self.messages:
@ -471,6 +472,24 @@ class guiChannel:
def setReady(self):
self.ready = True
def getMessageTimePath(channel):
return p(loginPath,"messageTimes",str(channel.id))
def getLastMessageTime(channel):
mtpath = getMessageTimePath(channel)
if not os.path.isfile(mtpath): return None
try:
return datetime.fromisoformat(open(mtpath,"r").read())
except:
print("reading old time failed, ditching")
return None
def setLastMessageTime(channel,time):
mtpath = getMessageTimePath(channel)
fh = open(mtpath,"w")
fh.write(time.isoformat())
fh.close()
def discordClient(token):
logging.basicConfig(level=logging.INFO)
loop = asyncio.new_event_loop()
@ -478,9 +497,15 @@ def discordClient(token):
global client
client = discord.Client()
global channelFilter
channelFilter = (discord.DMChannel,discord.GroupChannel)
global loginPath
@client.event
async def on_ready():
print("on_ready")
global online
global channelFilter
global ready
if ready == False:
condition = threading.Condition()
@ -509,15 +534,81 @@ def discordClient(token):
guiLoop.start()
ready = True
print("on_ready")
if config["messageTracking"]["trackMessages"] == "true" and config["messageTracking"]["recheckMessages"] == "true":
for channel in client.private_channels:
if not type(channel) in channelFilter: continue
newTime = None
async for msg in channel.history(limit=1):
newTime = msg.created_at
if not newTime: continue
oldTime = getLastMessageTime(channel)
if not oldTime:
setLastMessageTime(channel,newTime)
continue
async for message in history(limit=100,before=newTime,after=oldTime):
guiLock.acquire()
for gui in openGuis:
if gui.type == "channel":
if message.channel != gui.channel: continue
addGuiTask(gui,gui.addMessage,(message,),{})
guiLock.release()
if online == False:
online = True
@client.event
async def on_resumed():
print("on_resumed")
global online
global channelFilter
if config["messageTracking"]["trackMessages"] == "true" and config["messageTracking"]["recheckMessages"] == "true":
for channel in client.private_channels:
if not type(channel) in channelFilter: continue
newTime = None
async for msg in channel.history(limit=1):
newTime = msg.created_at
if not newTime: continue
oldTime = getLastMessageTime(channel)
if not oldTime:
setLastMessageTime(channel,newTime)
continue
async for message in history(limit=100,before=newTime,after=oldTime):
guiLock.acquire()
for gui in openGuis:
if gui.type == "channel":
if message.channel != gui.channel: continue
addGuiTask(gui,gui.addMessage,(message,),{})
guiLock.release()
if online == False:
online = True
@client.event
async def on_message(message):
messages = [message]
if type(message.channel) in channelFilter and config["messageTracking"]["trackMessages"] == "true":
oldTime = getLastMessageTime(message.channel)
if oldTime:
if config["messageTracking"]["paranoidMessages"] == "true":
async for msg in message.channel.history(limit=100,before=message.created_at,after=oldTime):
print("[paranoidMessages] post-fetching message")
messages = msg + messages
setLastMessageTime(message.channel,message.created_at)
guiLock.acquire()
for gui in openGuis:
if gui.type == "channel":
if message.channel != gui.channel: continue
addGuiTask(gui,gui.addMessage,(message,),{})
for msg in messages:
addGuiTask(gui,gui.addMessage,(msg,),{})
guiLock.release()
@tasks.loop(seconds=0.033)
@ -571,8 +662,10 @@ def init(nlogin):
global login
login = nlogin
global loginPath
loginPath = p(pathLogins,login)
token = ""
with open(p(pathLogins,login,"token")) as tokenFile:
with open(p(loginPath,"token")) as tokenFile:
token = tokenFile.read()
guiLock.acquire()
@ -634,8 +727,6 @@ def main():
global config
config = configparser.ConfigParser()
config.read(p(sp,"default.ini"))
global maxMessages
maxMessages = int(config["performance"]["maxMessagesListed"])
global app
app = dbfApp()