| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- from importlib.resources import contents
- from Stats import Stats
- import configparser
- from lib.Network import Network
- from Jessi import ContentFile
- from Jessi import Contents
- import datetime
- import math
- import json
- import random
- import lib.MoonPhase as mp
- import os
- import re
- class NummericPronounce:
- Normal = 0
- Year = 1
- Time = 2
- class Text:
-
- instance = None
- content = dict()
- @staticmethod
- def getInstance():
- if Text.instance==None:
- Text.instance = Text()
- return Text.instance
- def __init__(self):
- self.stats:Stats = Stats.getInstance()
- self.config = configparser.ConfigParser()
- self.config.read("config/config.ini")
- self.replacer = list()
- # TODO: Replacer.js laden, und alle 60-180 Sekunden eine List-Variable mit möglichen Antworten füllen / aktualisieren
- # z.B. aus der Replacer.js "badwords" mit allen möglichen Antworten, abhängig der Requirements, in die Variable "replacer["badwords"][]" füllen
- # Weitere mögliche Wortlisten: "niceword" (incl cuteness, wenn verspieltheit hoch ist)
- self.readReplacer()
-
- def getText(self, intent:str, tags) -> Contents:
- if intent not in self.content:
- if os.path.isfile("ressources/texts/"+intent+".json") == False:
- print("Failed to load intent text: "+intent)
- return ""
- self.content[intent] = ContentFile.ContentFile(intent+".json")
- return self.content[intent].getText(tags)
- def executeText(self, intent:str, tags) -> str:
- if intent not in self.content:
- if os.path.isfile("ressources/texts/"+intent+".json") == False:
- print("Failed to load intent text: "+intent)
- return ""
- self.content[intent] = ContentFile.ContentFile(intent+".json")
- return self.formatText(self.content[intent].executeText(tags))
- def formatText(self, text:str ) -> str:
- if text.find("{"):
- if text.find("{device."):
- text = text.replace("{device.name}",self.config["global"]["DeviceName"])
- text = text.replace("{device.owner}",self.config["global"]["Owner"])
- text = text.replace("{device.ip}", Network.getIp())
- text = text.replace("{device.host}", Network.getHostName())
- text = text.replace("{device.hostname}", Network.getHostName())
- if text.find("{datetime."):
- #Tomorow: datetime.datetime.now() + datetime.timedelta(days=1)
- #Yesterday: datetime.datetime.now() - datetime.timedelta(days=1)
- text = self._formatText_DateTime(text,datetime.datetime.now(),"now")
- text = self._formatText_DateTime(text,datetime.datetime.now() + datetime.timedelta(days=1),"tomorow")
- text = self._formatText_DateTime(text,datetime.datetime.now() - datetime.timedelta(days=1),"yesterday")
- text = self._formatText_DateTime(text,datetime.datetime.now() - datetime.timedelta(days=1),"morning") #TODO
- text = self._formatText_DateTime(text,datetime.datetime.now() - datetime.timedelta(days=1),"midday") #TODO
- text = self._formatText_DateTime(text,datetime.datetime.now() - datetime.timedelta(days=1),"evening") #TODO
- text = self._formatText_DateTime(text,datetime.datetime.now() - datetime.timedelta(days=1),"night") #TODO
- if text.find("{weather."):
- pass
- if text.find("{house."):
- pass
- if text.find("{event."):
- pass
- if text.find("{calender."):
- pass
- if text.find("{"):
- print("Enter Replacer Loop")
- deadcounter=0
- for k in self.replacer:
- print("- Search for '"+k+"'")
- notfound=False
- while notfound==False:
- if text.find("{"+k+"|") >= 0:
- print("- found {"+k+"|")
- word = self.getRandomWord(self.replacer[k])
- if word=="":
- text = re.sub("\\{"+k+"(?:\\|([a-z]{0,5}))?\\}","",text,1)
- else:
- text = re.sub("\\{"+k+"(?:\\|([a-z]{0,5}))?\\}",word+"\\1",text,1)
- #pos1 = text.find("{"+k+"|")
- #pos2 = pos1 + 2 + len(k)
- #pos3 = text.find("}",pos1)
- #res = text[0:pos1] + word + text[pos2:pos3-pos2] + text[pos3:]
- #text=res
- elif text.find("{"+k+"}") >= 0:
- print("- found {"+k+"}")
- text = re.sub("\\{"+k+"\\}",self.getRandomWord(self.replacer[k]),text,1)
- else:
- notfound=True
- break
- deadcounter+=1
- if deadcounter > 40:
- break
- print("Exit Replacer Loop")
- return text
- def _formatText_DateTime(self,text:str,dt:datetime.datetime,name:str):
- name="{datetime."+name+"."
- if text.find(name):
- dt = datetime.datetime.now() + datetime.timedelta(days=1)
- text = text.replace(name+"weekday}", self.getWeekDay(dt.weekday()) )
- text = text.replace(name+"year}", self.getNumericPronounce(dt.year,0, NummericPronounce.Year) )
- text = text.replace(name+"month}", self.getMonthName(dt.month) )
- text = text.replace(name+"day}", self.getNumericDottedPronounce(dt.day) )
- text = text.replace(name+"hour}", self.getNumericPronounce(dt.hour) )
- text = text.replace(name+"minute}", self.getNumericPronounce(dt.minute) )
- text = text.replace(name+"seconds}", self.getNumericPronounce(dt.second) )
- text = text.replace(name+"second}", self.getNumericPronounce(dt.second) )
- text = text.replace(name+"}", self.getDateString(dt) )
- text = text.replace(name+"moonphase}", mp.phase(time=dt)["name"] )
- return text
- def getRandomWord(self, items:list) -> str:
- if len(items) > 0:
- return random.choice(items)
- else:
- return ""
- def readReplacer(self):
- tmp = {}
- with open("ressources/texts/Replacer.json", encoding="utf-8") as json_file:
- data = json.load(json_file)
- for k in data:
- tmp[k] = list()
- add = True
- for i in data[k]:
- if "mood_required" in i:
- statKeys = ["angry","annoyed","aroused","bored","compfortable","depressive","energy","excited","exhausted",
- "freezy","funny","happyness","hot","humanity","hungry","intelligent","irritated","lonely","naiv",
- "playful","sad","shy","sleepy","soziality","temperate","toLoud","toQuiet","usefull","useless"]
- for sk in statKeys:
- if sk+"_max" in i["mood_required"] and i["mood_required"][sk+"_max"] <= getattr(self.stats.DeviceStats,sk):
- add = False
- break
- if sk+"_min" in i["mood_required"] and i["mood_required"][sk+"_min"] >= getattr(self.stats.DeviceStats,sk):
- add = False
- break
- if add == True and "text" in i:
- for t in i["text"]:
- tmp[k].append(t)
- self.replacer = tmp
- @staticmethod
- def getWeekDay(weekday:int) -> str:
- weekdays = [
- "Sonntag",
- "Montag",
- "Dienstag",
- "Mittwoch",
- "Donnerstag",
- "Freitag",
- "Samstag",
- "Sonntag"
- ]
- return weekdays[weekday]
- @staticmethod
- def getMonthName(month:int) -> str:
- monthnames = [
- "",
- "Januar",
- "Februar",
- "März",
- "April",
- "Mai",
- "Juni",
- "Juli",
- "August",
- "September",
- "Oktober",
- "November",
- "Dezember"
- ]
- return monthnames[month]
- @staticmethod
- def getNumericPronounce(num:float, decimals:int = 2, type:int = NummericPronounce.Normal) -> str:
- ''' Formats a integer or floating point value into a readable string
- num:float - The Number that should be writeable
- decimals:int - the amount of decimals (max 6)
- Range: -999,999,999.999999 to 999,999,999.999999
-
- Returns :str'''
- if type == NummericPronounce.Year:
- s2=""
- if num<0:
- num*=-1
- s2=" vor Christus"
- if num>=1300 and num<2200:
- num3 = math.floor(num/100)
- s = Text.getNumericPronounce(num3)
- num2 = num % 100
- if(num2>9):
- s += " " + Text.getNumericPronounce(num2)
- else:
- s += " null " + Text.getNumericPronounce(num2 % 10)
- return s+s2
- else:
- # Check for negative numbers
- if num<0:
- return "Minus " + Text.getNumericPronounce(num * -1)
- # Check for decimal
- if math.floor(num)!=math.ceil(num):
- if decimals<1:
- num=math.floor(num)
- else:
- s = Text.getNumericPronounce(math.floor(num))
- num -= math.floor(num)
- s+=" Komma"
- s+= " " + Text.getNumericPronounce(math.floor(num*10)%10)
- if decimals>=2: s+= " " + Text.getNumericPronounce(math.floor(num*100)%10)
- if decimals>=3: s+= " " + Text.getNumericPronounce(math.floor(num*1000)%10)
- if decimals>=4: s+= " " + Text.getNumericPronounce(math.floor(num*10000)%10)
- if decimals>=5: s+= " " + Text.getNumericPronounce(math.floor(num*100000)%10)
- if decimals>=6: s+= " " + Text.getNumericPronounce(math.floor(num*1000000)%10)
- return s
- mod = num%10
- zehner=(num-mod) % 100
- hunderter=(num-mod-zehner) % 1000
- tausender=(num-mod-zehner-hunderter) % 1000000
- millonener=(num-mod-zehner-hunderter-tausender) % 1000000000
- if num==0: return "null"
- elif num==1: return "eins" # handels 1 only
- elif num==2: return "zwei" # handels 2, 200, 302, 2.000, 2.000.000
- elif num==3: return "drei"
- elif num==4: return "vier"
- elif num==5: return "fünf"
- elif num==6: return "sechs"
- elif num==7: return "sieben"
- elif num==8: return "acht"
- elif num==9: return "neun"
- elif num==10: return "zehn"
- elif num==11: return "elf"
- elif num==12: return "zwölf"
- elif num<=19: return Text.getNumericPronounce(mod)+"zehn"
- elif num==20: return "zwanzig"
- elif num==30: return "dreissig"
- elif num==60: return "sechzig"
- elif num==70: return "siebzig"
- elif num<=99 and mod == 0: return Text.getNumericPronounce(zehner/10)+"zig"
- elif num<=99 and mod == 1: return "einund"+Text.getNumericPronounce(zehner) # handels 21, 31, 41, 51, ...
- elif num<=99 and mod > 1: return Text.getNumericPronounce(mod) + "und"+ Text.getNumericPronounce(zehner) #handels 22, 23, 24, 25, ... 32, 33, 34, ..., 42, 53, ....
- elif num==100: return "einhundert" # handels 100
- elif num<=199: return "einhundert" + Text.getNumericPronounce(num%100) # handels 101, 102, 103, ...
- elif num<=999 and num%100==0: return Text.getNumericPronounce(hunderter/100)+"hundert" # handels 200, 300, 400, 500, 600, 700, 800, 900
- elif num<=999: return Text.getNumericPronounce(hunderter/100)+"hundert"+Text.getNumericPronounce(num%100) # handels 201, 202, ... 301, 302
- elif num==1000: return "eintausend"
- elif num==10000: return "zehntausend"
- elif num==100000: return "einhunderttausend"
- elif num==1000000: return "eine millionen"
- elif num<=1999: return "eintausend"+Text.getNumericPronounce(num%1000)
- elif num<=999999 and num%1000==0: return Text.getNumericPronounce(tausender/1000)+"tausend" # handels 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000
- elif num<=999999: return Text.getNumericPronounce(tausender/1000)+"tausend "+Text.getNumericPronounce(num%1000)
- elif num<=1999999: return "eine millionen "+Text.getNumericPronounce(millonener%1000000)
- elif num<=999999999 and num%1000000==0: return Text.getNumericPronounce(millonener/1000000)+" millionen" # handels 2mio, 3mio, 4mio, 5mio, 6mio, 7mio, 8mio, 9mio
- elif num<=999999999: return Text.getNumericPronounce(millonener/1000000)+" millionen "+Text.getNumericPronounce(num%1000000)
- else: print("ErrNum: "+num)
- @staticmethod
- def getNumericDottedPronounce(num:int) -> str:
- if num==1:
- return "erste"
- elif num==3:
- return "dritte"
- elif num==8:
- return "achte"
- elif num>= 20:
- return Text.getNumericPronounce(num)+"ste"
- else:
- return Text.getNumericPronounce(num)+"te"
- @staticmethod
- def getDateString(date, WeekDay:bool = True, Year:bool = True) -> str:
- if WeekDay and Year:
- return Text.getWeekDay(date.weekday())+", der "+Text.getNumericDottedPronounce(date.day)+" "+Text.getMonthName(date.month)+" "+Text.getNumericPronounce(date.year, 0, NummericPronounce.Year)
- pass
- elif WeekDay:
- return Text.getWeekDay(date.weekday())+", der "+Text.getNumericDottedPronounce(date.day)+" "+Text.getMonthName(date.month)
- elif Year:
- return Text.getNumericDottedPronounce(date.day)+" "+Text.getMonthName(date.month)+" "+Text.getNumericPronounce(date.year, 0, NummericPronounce.Year)
- else:
- return Text.getNumericDottedPronounce(date.day)+" "+Text.getMonthName(date.month)
-
- @staticmethod
- def getTimeString(time, Seconds:bool=False, Use24:bool=False) -> str:
- if Seconds:
- return Text.getTimeString(time,False,Use24)+" und " + time.seconds+" Sekunden"
- else:
- min = time.minute
- sur=""
- surn=""
- if Use24:
- hour=Text.getNumericPronounce(time.hour)
- hourn=Text.getNumericPronounce((time.hour+1)%24)
- else:
- hour=Text.getNumericPronounce(time.hour%12)
- hourn=Text.getNumericPronounce((time.hour+1)%12)
- if time.hour<5 or time.hour>21: sur=" Nachts"
- elif time.hour<11: sur=" Morgens"
- elif time.hour<16: sur=" Mittags"
- elif time.hour<19: sur=" Nachmittags"
- else: sur=" Abends"
- if time.hour<4 or time.hour>20: surn=" Nachts"
- elif time.hour<10: surn=" Morgens"
- elif time.hour<15: surn=" Mittags"
- elif time.hour<18: surn=" Nachmittags"
- else: surn=" Abends"
- if time.hour==23:
- shour=hour
- shourn="Mitternacht"
- elif time==0:
- shour="Mitternacht"
- shourn=hourn
- else:
- shour=hour
- shourn=hourn
- if min==0:
- return "punkt "+shour+sur
- elif min==30:
- return "halb "+shourn+surn
- elif min>=27 and min<30:
- return "kurz vor halb "+shourn+surn
- elif min>30 and min<=33:
- return "kurz nach halb "+shourn+surn
- elif min==15:
- return "viertel nach "+shour+sur
- elif min==45:
- return "viertel vor "+shourn+surn
- elif min<=3:
- return "kurz nach "+shour+sur
- elif min>=37:
- return "kurz vor "+shourn+surn
- else:
- return hour+" Uhr "+Text.getNumericPronounce(min)+sur
|