fixed, bug where the stats are not reseted, changed json output format, added listz selection
This commit is contained in:
parent
32b6e41b97
commit
14b2a584a7
143
src/main.py
143
src/main.py
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
from telethon import TelegramClient, sync
|
||||
from telethon.tl.types import User
|
||||
from timeit import default_timer as timer
|
||||
import configparser
|
||||
import out
|
||||
|
@ -7,6 +8,7 @@ import math, datetime
|
|||
import colorama
|
||||
from colorama import Fore, Style
|
||||
|
||||
|
||||
class Stat:
|
||||
name = None
|
||||
|
||||
|
@ -42,10 +44,13 @@ class Countable(Stat):
|
|||
min = 1 << 31
|
||||
max = 0
|
||||
|
||||
"""def getValue(self, count):
|
||||
return "Min: " + self.getMin() + " Max: " + self.getMax() + " Gesamt: " \
|
||||
+ self.getAcc() + " Avg: " + self.getAvg(count) + " Geom.Avg: " + self.getGAvg()
|
||||
"""
|
||||
def __init__(self, name):
|
||||
self.acc = 0
|
||||
self.mult = 0
|
||||
self.min = 1 << 31
|
||||
self.max = 0
|
||||
super().__init__(name)
|
||||
|
||||
def getMin(self):
|
||||
return self.parse(self.min)
|
||||
|
||||
|
@ -62,7 +67,8 @@ class Countable(Stat):
|
|||
return self.parse(math.sqrt(self.mult))
|
||||
|
||||
def getAll(self, count):
|
||||
return {'min': self.getMin(), 'max': self.getMax(), 'count': self.getAcc(), 'avg': self.getAvg(count), 'gavg': self.getGAvg()}
|
||||
return {'min': self.getMin(), 'max': self.getMax(), 'count': self.getAcc(), 'avg': self.getAvg(count),
|
||||
'gavg': self.getGAvg()}
|
||||
|
||||
def addMsg(self, msgnum, msg, chat):
|
||||
count = self.count(msgnum, msg, chat)
|
||||
|
@ -92,6 +98,7 @@ class Dist(Countable):
|
|||
prev = 0
|
||||
|
||||
def __init__(self, name: str = "Distanz"):
|
||||
self.prev = 0
|
||||
super().__init__(name)
|
||||
|
||||
def count(self, msgnum, msg, chat):
|
||||
|
@ -108,20 +115,16 @@ class Dist(Countable):
|
|||
def getAvg(self, count):
|
||||
if count < 2:
|
||||
return -1
|
||||
return self.parse(int(self.acc / (count-1))) # da hier die abstände zwischen nachrichten betrachtet werden ist es um 1 kleiner
|
||||
return self.parse(int(
|
||||
self.acc / (count - 1))) # da hier die abstände zwischen nachrichten betrachtet werden ist es um 1 kleiner
|
||||
|
||||
|
||||
class DiscreteCount(Stat):
|
||||
list = {}
|
||||
|
||||
"""def getValue(self, count):
|
||||
out = ''
|
||||
# sorted_ = sorted(list.items(), key=lambda kv: kv[1])
|
||||
for name, count in self.list.items():
|
||||
if len(out) > 0:
|
||||
out = out + ", "
|
||||
out = out + name + ": " + str(count)
|
||||
return out;"""
|
||||
def __init__(self, name):
|
||||
self.list = {}
|
||||
super().__init__(name)
|
||||
|
||||
def getAll(self, count):
|
||||
return self.list
|
||||
|
@ -137,7 +140,6 @@ class UserCount(DiscreteCount):
|
|||
fromid = msg.from_id
|
||||
self.list[fromid] = self.list.get(fromid, 0) + 1
|
||||
|
||||
|
||||
def getAll(self, count):
|
||||
# replace ids with names
|
||||
newdict = {}
|
||||
|
@ -151,7 +153,19 @@ def printDialog(interid, d): # debug only
|
|||
color = ''
|
||||
if interid & 1:
|
||||
color = Fore.LIGHTBLACK_EX
|
||||
print(color + '{0:3d}| {1:14d} | {2:30} | {3:1}'.format(interid, d.id, d.name, d.pinned) + Fore.RESET)
|
||||
print(color + '{0:3d}| {1:14d} | {2:30} | {3:1}'.format(interid, d.id, getDialogType(d) + d.name,
|
||||
d.pinned) + Fore.RESET)
|
||||
|
||||
|
||||
def getDialogType(dialog):
|
||||
if dialog.id < 0: # group
|
||||
return '👥'
|
||||
|
||||
ent = dialog.entity
|
||||
if isinstance(ent, User):
|
||||
if ent.bot:
|
||||
return '🤖'
|
||||
return '👤'
|
||||
|
||||
|
||||
def getUsernamebyID(userid):
|
||||
|
@ -161,12 +175,39 @@ def getUsernamebyID(userid):
|
|||
return d.name
|
||||
return "Unknown" # refresh dialog cache?
|
||||
|
||||
|
||||
def dialogByTgID(tgid):
|
||||
global dialogs
|
||||
for d in dialogs:
|
||||
if d.id == tgid:
|
||||
return d
|
||||
return None
|
||||
|
||||
|
||||
def dialogByTgName(name):
|
||||
name = name.lower()
|
||||
global dialogs
|
||||
for d in dialogs:
|
||||
if d.name.lower() == name:
|
||||
return d
|
||||
return None
|
||||
|
||||
|
||||
def analyseChat(dialog, output):
|
||||
print(Fore.GREEN + 'Lade kompletten Chat: ' + Fore.RESET, dialog.name, sep='')
|
||||
|
||||
# chat = client.get_messages(selectedDialog)
|
||||
chat = client.iter_messages(dialog, limit=None)
|
||||
|
||||
stats = {
|
||||
CharCount(),
|
||||
Dist(),
|
||||
UserCount()
|
||||
}
|
||||
"""print('before' + Fore.MAGENTA)
|
||||
outputs['stdout'].print(stats, 10, dialog)
|
||||
print(Fore.RESET + 'after' + Fore.BLUE)"""
|
||||
|
||||
# run messure
|
||||
msgnum = 0
|
||||
for msg in chat:
|
||||
|
@ -180,15 +221,41 @@ def analyseChat(dialog, output):
|
|||
# write to output
|
||||
output.print(stats, msgnum, dialog)
|
||||
|
||||
|
||||
def parseInput(uinput):
|
||||
selected = []
|
||||
if uinput == 'all':
|
||||
selected = dialogs
|
||||
else:
|
||||
splited = uinput.split(',')
|
||||
for entry in splited:
|
||||
entry = entry.strip()
|
||||
if not entry: # empty string
|
||||
continue
|
||||
if entry.isnumeric():
|
||||
get = int(entry)
|
||||
if get >= 0 and get < dialogCount: # use id
|
||||
selected.append(dialogs[get])
|
||||
continue
|
||||
|
||||
# search by id
|
||||
bytgid = dialogByTgID(get)
|
||||
if bytgid is not None:
|
||||
selected.append(bytgid)
|
||||
continue
|
||||
# search by name
|
||||
bytgname = dialogByTgName(entry)
|
||||
if bytgname is not None:
|
||||
selected.append(bytgname)
|
||||
continue
|
||||
print(Fore.YELLOW + 'Kein Chat für Eingabe gefunden: ' + Fore.BLUE, entry, Fore.RESET)
|
||||
raise ValueError('unknown chat')
|
||||
return selected
|
||||
|
||||
|
||||
# ==================================
|
||||
# MAIN program
|
||||
if __name__ == "__main__":
|
||||
stats = {
|
||||
CharCount(),
|
||||
Dist(),
|
||||
UserCount()
|
||||
}
|
||||
|
||||
outputs = {
|
||||
"stdout": out.STDOUT(),
|
||||
"json": out.jsonOut()
|
||||
|
@ -217,7 +284,7 @@ if __name__ == "__main__":
|
|||
dialogCount = len(dialogs)
|
||||
print(Fore.YELLOW, dialogCount, Fore.GREEN + 'Chats geladen.' + Fore.RESET)
|
||||
|
||||
#select output
|
||||
# select output
|
||||
while True:
|
||||
uinput = input("Bitte Ausgabemethode wählen: [stdout,json] (stdout): ").strip().lower();
|
||||
if uinput == "":
|
||||
|
@ -233,27 +300,31 @@ if __name__ == "__main__":
|
|||
outfile = input("Bitte Dateinamen eingeben: ").strip()
|
||||
out.open(outfile)
|
||||
|
||||
#select chat
|
||||
print(' ID | Internal ID | Username | pinned\n———+————————————————+————————————————————————————————+———————')
|
||||
# select chat
|
||||
print(
|
||||
' ID| Internal ID | Username | pinned\n———+————————————————+————————————————————————————————+———————')
|
||||
interid = 0
|
||||
for d in dialogs:
|
||||
printDialog(interid, d)
|
||||
interid = interid + 1
|
||||
|
||||
uinput = input('Bitte ' + Fore.BLUE + 'chatid' + Fore.RESET + ' oder "' + Fore.BLUE + 'all' + Fore.RESET + '" eingeben: ').strip().lower() # TODO: select more than one or all
|
||||
while True:
|
||||
uinput = input(
|
||||
'Bitte ' + Fore.BLUE + 'chatid1,chatid2,...' + Fore.RESET + ' oder "' + Fore.BLUE + 'all' + Fore.RESET + '" eingeben: ').strip().lower()
|
||||
try:
|
||||
selected = parseInput(uinput)
|
||||
break
|
||||
except:
|
||||
pass # some error, retry
|
||||
|
||||
start = timer()
|
||||
if uinput == 'all':
|
||||
for d in dialogs:
|
||||
for d in selected:
|
||||
try:
|
||||
analyseChat(d, out)
|
||||
else:
|
||||
get = int(uinput)
|
||||
if get < 0 or get >= dialogCount: #TODO: detect user by username, name, tg-id
|
||||
print("unbekannte Chat ID!")
|
||||
exit(1)
|
||||
|
||||
analyseChat(dialogs[get], out)
|
||||
except Exception as e:
|
||||
print(Fore.RED + 'Fehler beim bearbeiten von: ' + Fore.RESET, d.name, '\n', e)
|
||||
print(e)
|
||||
out.close()
|
||||
took = datetime.timedelta(seconds=(timer()-start))
|
||||
took = datetime.timedelta(seconds=(timer() - start))
|
||||
took = datetime.timedelta(seconds=int(took.total_seconds()))
|
||||
print(Fore.GREEN + "Fertig. Benötigte Zeit: " + Fore.YELLOW, took, Style.RESET_ALL)
|
||||
|
|
|
@ -31,7 +31,7 @@ class jsonOut(Output):
|
|||
|
||||
file = None
|
||||
needsFilename = True
|
||||
outbuff = {}
|
||||
outbuff = []
|
||||
|
||||
def __init__(self, name: str = "json"):
|
||||
super().__init__(name)
|
||||
|
@ -46,7 +46,7 @@ class jsonOut(Output):
|
|||
self.file.close()
|
||||
|
||||
def print(self, stats, count, dialog):
|
||||
jsonpre = {"count": count}
|
||||
jsonpre = {"count": count, 'chatid': dialog.id, 'chatname': dialog.name}
|
||||
for stat in stats:
|
||||
jsonpre[stat.name] = stat.getAll(count)
|
||||
self.outbuff[dialog.id] = jsonpre
|
||||
self.outbuff.append(jsonpre)
|
||||
|
|
Loading…
Reference in New Issue