Added support for UTF8 emojis

This commit is contained in:
Fotoente 2022-02-20 13:53:13 +01:00
parent fb36e089b9
commit b11edc5c69
2 changed files with 169 additions and 129 deletions

3
.gitignore vendored
View file

@ -1,2 +1,3 @@
emojicount.cfg emojicount.cfg
miceco.cfg miceco.cfg
.idea

295
miceco.py
View file

@ -1,23 +1,26 @@
import sys
import os
import requests
from datetime import *
import json
import configparser import configparser
import os
import re
import sys
from datetime import *
import dateutil.relativedelta
def check_str_to_bool(text) -> bool: import requests
if (text == "True" or text == "true" or text == "TRUE"): import emoji as emojilib
def check_str_to_bool(input_text) -> bool:
if input_text == "True" or input_text == "true" or input_text == "TRUE":
return True return True
elif (text == "False" or text == "false" or text == "FALSE"): elif input_text == "False" or input_text == "false" or input_text == "FALSE":
return False return False
else: else:
return True return True
token=""
url=""
noteList = [] noteList = []
reactionList = [] reactionList = []
reactList=[] reactList = []
emojiList = [] emojiList = []
emojisTotal = 0 emojisTotal = 0
doubleList = [] doubleList = []
@ -26,186 +29,222 @@ getReactions = False
configfilePath = os.path.join(os.path.dirname(__file__), 'miceco.cfg') configfilePath = os.path.join(os.path.dirname(__file__), 'miceco.cfg')
if (not os.path.exists(configfilePath)): if not os.path.exists(configfilePath):
print("No config File found!") print("No config File found!")
print("Exit programm!") print("Exit program!")
sys.exit(1) sys.exit(1)
#Load configuration # Load configuration
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(configfilePath) config.read(configfilePath)
url = "https://" + config.get("misskey","instance") + "/api" url = "https://" + config.get("misskey", "instance") + "/api"
token = config.get("misskey","token") token = config.get("misskey", "token")
user = config.get("misskey","user") user = config.get("misskey", "user")
try: try:
getReactions = check_str_to_bool(config.get("misskey","getReaction")) getReactions = check_str_to_bool(config.get("misskey", "getReaction"))
except (TypeError, ValueError) as err: except (TypeError, ValueError) as err:
getReactions = False getReactions = False
try: try:
req = requests.post(url+"/users/show", json={"username" : user, "host" : None, "i" : token}) req = requests.post(url + "/users/show", json={"username": user, "host": None, "i": token})
req.raise_for_status() req.raise_for_status()
except requests.exceptions.HTTPError as err: except requests.exceptions.HTTPError as err:
print("Couldn't get Username!\n"+str(err)) print("Couldn't get Username!\n" + str(err))
sys.exit(1) sys.exit(1)
userid = req.json()["id"] userid = req.json()["id"]
nickname = req.json()["name"] nickname = req.json()["name"]
heute = date.today() today = date.today()
gestern = heute - timedelta(days = 1) formerDate = today - timedelta(days=1)
mitternachtGestern = datetime.combine(gestern, time(0,0,0)) # formerDate = today - timedelta(weeks=1) #Last week
mitternachtHeute = datetime.combine(heute, time(0,0,0)) # formerDate = today - dateutil.relativedelta.relativedelta(months=1)
formerDateMidnight = datetime.combine(formerDate, time(0, 0, 0))
todayMidnight = datetime.combine(today, time(0, 0, 0))
seit = int(mitternachtGestern.timestamp())*1000 #Javascript uses millisecond timestamp and Python uses float seit = int(formerDateMidnight.timestamp()) * 1000 # Javascript uses millisecond timestamp and Python uses float
bis = int(mitternachtHeute.timestamp())*1000 bis = int(todayMidnight.timestamp()) * 1000
lastTimestamp = bis lastTimestamp = bis
formerTimestamp = 0
while True: while True:
if (bis != lastTimestamp) and (formerTimestamp == lastTimestamp):
if ((bis != lastTimestamp) and (formerTimestamp == lastTimestamp)):
break break
try: try:
req = requests.post(url+"/users/notes", json = { req = requests.post(url + "/users/notes", json={
"i" : token, "i": token,
"userId" : userid, "userId": userid,
"sinceDate" : seit, "sinceDate": seit,
"untilDate" : lastTimestamp, "untilDate": lastTimestamp,
"includeReplies" : True, "includeReplies": True,
"limit" : 100, "limit": 100,
"includeMyRenotes" : False, "includeMyRenotes": False,
"withFiles" : False, "withFiles": False,
"excludeNsfw" : False "excludeNsfw": False
}) })
req.raise_for_status() req.raise_for_status()
except requests.exceptions.HTTPError as err: except requests.exceptions.HTTPError as err:
print("Couldn't get Posts! "+str(err)) print("Couldn't get Posts! " + str(err))
sys.exit(1) sys.exit(1)
for jsonObj in req.json(): for jsonObj in req.json():
#textDict = jsonObj # textDict = jsonObj
noteList.append(jsonObj) noteList.append(jsonObj)
formerTimestamp = lastTimestamp formerTimestamp = lastTimestamp
lastTime = noteList[len(noteList)-1]["createdAt"] lastTime = noteList[len(noteList) - 1]["createdAt"]
lastTimestamp = int(datetime.timestamp(datetime.strptime(lastTime, '%Y-%m-%dT%H:%M:%S.%f%z'))*1000) lastTimestamp = int(datetime.timestamp(datetime.strptime(lastTime, '%Y-%m-%dT%H:%M:%S.%f%z')) * 1000)
for element in noteList: for element in noteList:
if (element["text"] == None): #Skip Notes without text if element["text"] is None: # Skip Notes without text
print("Skip Note " + element["id"] + " without Text\nTime noted: " + element["createdAt"]) print("Skip Note " + element["id"] + " without Text\nTime noted: " + element["createdAt"])
continue continue
if (element["text"].find(chr(8203))>0): #Skip notes with Zero-Width-Space (Marker to skip older MiCECo notes) if element["text"].find(chr(8203) + chr(8203) + chr(8203)) > 0: # Skip notes with three Zero-Width-Space in a
# row (Marker to skip older MiCECo notes)
print("Skip Note " + element["id"] + " with Zero-Width-Space\nTime noted: " + element["createdAt"]) print("Skip Note " + element["id"] + " with Zero-Width-Space\nTime noted: " + element["createdAt"])
continue continue
# Process and count custom Emojis
emojis = element["emojis"] emojis = element["emojis"]
if emojis is not None:
for emoji in emojis:
if emoji["name"].find("@") == -1: # Only emojis from the own instance, because reactions will be in "emojis"
# too
if not emoji["name"] in doubleList:
doubleList.append(emoji["name"]) # Easy way to prevent a double emoji in the list.
emojiDict = {"emoji": ":" + emoji["name"] + ":", "count": 0}
emojiList.append(emojiDict)
else:
continue
index = doubleList.index(emoji["name"])
emojiList[index]["count"] += element["text"].count(emojiList[index]["emoji"])
if element["cw"] is not None:
emojiList[index]["count"] += element["cw"].count(emojiList[index]["emoji"]) # Count those Emojis, that
# are in this note CW text
if (not emojis): #Notes without emojis will be skipped # Process UTF8 Emojis
continue if element["cw"] is not None:
UTF8text = element["text"] + " " + element["cw"]
for emoji in emojis: else:
if (emoji["name"].find("@") == -1): #Only emojis from the own instance, because reactions will be in "emojis" too UTF8text = element["text"]
if (not emoji["name"] in doubleList): UTF8List = re.findall(emojilib.get_emoji_regexp(), UTF8text) # Find all UTF8 Emojis in Text and CW text
doubleList.append(emoji["name"]) #Easy way to prevent a double emoji in the list.
dict={"emoji" : emoji["name"], "count" : 0} if len(UTF8List) > 0:
emojiList.append(dict) #TODO: Append a dictionary to acces it way easier UTF8List = list(set(UTF8List))
for emoji in UTF8List:
for emoji in emojiList: if emoji not in doubleList:
emoji["count"] += element["text"].count(emoji["emoji"]) #Count those Emojis, that are in this note doubleList.append(emoji) # Easy way to prevent a double emoji in the list.
emojiDict = {"emoji": emoji, "count": 0}
if (element["cw"] is not None): emojiList.append(emojiDict)
emoji["count"] += element["cw"].count(emoji["emoji"]) #Count those Emojis, that are in this note
index = doubleList.index(emoji)
emojiList[index]["count"] += UTF8text.count(emoji)
doubleList = [] doubleList = []
emojiList = sorted(emojiList, reverse = True , key = lambda d: d["count"]) #Sort it by the most used Emojis! emojiList = sorted(emojiList, reverse=True, key=lambda d: d["count"]) # Sort it by the most used Emojis!
reactionCount = 0
if getReactions: if getReactions:
lastTimestamp = bis lastTimestamp = bis
while True: while True:
if ((bis != lastTimestamp) and (formerTimestamp == lastTimestamp)): if (bis != lastTimestamp) and (formerTimestamp == lastTimestamp):
break break
try: try:
req = requests.post(url+"/users/reactions", json = { req = requests.post(url + "/users/reactions", json={
"i" : token, "i": token,
"userId" : userid, "userId": userid,
"sinceDate" : seit, "sinceDate": seit,
"untilDate" : lastTimestamp "untilDate": lastTimestamp
}) })
req.raise_for_status() req.raise_for_status()
except requests.exceptions.HTTPError as err: except requests.exceptions.HTTPError as err:
print("Couldn't get Posts! "+str(err)) print("Couldn't get Posts! " + str(err))
sys.exit(1) sys.exit(1)
for jsonObj in req.json(): for jsonObj in req.json():
#textDict = jsonObj # textDict = jsonObj
reactionList.append(jsonObj) reactionList.append(jsonObj)
formerTimestamp = lastTimestamp
lastTime = reactionList[len(reactionList)-1]["createdAt"]
lastTimestamp = int(datetime.timestamp(datetime.strptime(lastTime, '%Y-%m-%dT%H:%M:%S.%f%z'))*1000)
for reaction in reactionList: formerTimestamp = lastTimestamp
react = reaction["type"]
react = react.replace("@.","") lastTime = reactionList[len(reactionList) - 1]["createdAt"]
lastTimestamp = int(datetime.timestamp(datetime.strptime(lastTime, '%Y-%m-%dT%H:%M:%S.%f%z')) * 1000)
if (not react in doubleList):
react = ""
index = None
reactionElement: dict
for reactionElement in reactionList:
react = reactionElement["type"]
react = react.replace("@.", "")
if react not in doubleList:
doubleList.append(react) doubleList.append(react)
dict={"reaction" : react, "count" : 0} emojiDict = {"reaction": react, "count": 0}
reactList.append(dict) reactList.append(emojiDict)
for reaction in reactList: index = doubleList.index(react)
if (reaction["reaction"] == react):
reaction["count"] += 1 reactList[index]["count"] += 1
reactList = sorted(reactList, reverse = True , key = lambda d: d["count"]) doubleList = []
reactList = sorted(reactList, reverse=True, key=lambda d: d["count"])
reactionCount = 0
for react in reactList: if len(reactList) > 0:
for react in reactList: # Summarize the number of Reactions used
reactionCount += react["count"] reactionCount += react["count"]
if (len(reactList) > 0): reactText = "\n\n\nAnd used " + str(reactionCount) + " reactions:\n\n" + chr(9553) + " "
reactText="\n\n\nAnd used " + str(reactionCount) + " reactions:\n\n" + chr(9553) + " "
for reactionElement in reactList:
for reaction in reactList: reactText += str(reactionElement["count"]) + "x " + reactionElement["reaction"] + " " + chr(9553) + " "
reactText += str(reaction["count"]) + "x " + reaction["reaction"] + " " + chr(9553) + " "
else: else:
reactText="\n\nAnd didn't use any reactions." reactText = "\n\nAnd didn't use any reactions."
else: else:
reactText="" reactText = ""
for count in emojiList: for count in emojiList:
emojisTotal += count["count"] emojisTotal += count["count"]
if (emojisTotal > 0): if emojisTotal > 0:
text = nickname + " has written " + str(len(noteList)) + " Notes yesterday, " + gestern.strftime('%a %d-%m-%Y') + "\nand used a total of " + str(emojisTotal) + " Emojis. #miceco" + chr(8203) + "\n\n" + chr(9553) + " " text = nickname + " has written " + str(len(noteList)) + " Notes yesterday, " + formerDate.strftime(
'%a %d-%m-%Y') + "\nand used a total of " + str(emojisTotal) + " Emojis. #miceco" + chr(8203) + chr(8203) + chr(
8203) + "\n\n" + chr(
9553) + " "
for element in emojiList: for element in emojiList:
text += str(element["count"]) + "x\u00A0:" + element["emoji"] + ": " + chr(9553) + " " text += str(element["count"]) + "x\u00A0" + element["emoji"] + " " + chr(9553) + " "
else: else:
text = nickname + " has written " + str(len(noteList)) + " Notes yesterday, " + gestern.strftime('%a %d-%m-%Y') + "\nand didn't used any emojis. #miceco" + chr(8203) text = nickname + " has written " + str(len(noteList)) + " Notes yesterday, " + formerDate.strftime(
'%a %d-%m-%Y') + "\nand didn't used any emojis. #miceco" + chr(8203) + chr(8203) + chr(
8203)
text += reactText text += reactText
#print(text) print(text)
"""
try: try:
req = requests.post(url+"/notes/create", json = { req = requests.post(url + "/notes/create", json={
"i" : token, "i": token,
"visibility": "public", "visibility": "specified",
"text": text "text": text
}) })
req.raise_for_status() req.raise_for_status()
except requests.exceptions.HTTPError as err: except requests.exceptions.HTTPError as err:
print("Couldn't create Posts! "+str(err)) print("Couldn't create Posts! " + str(err))
sys.exit(1) sys.exit(1)
"""