diff --git a/.gitignore b/.gitignore
index e6b99fd..075724e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
# Persistence
-prst.db.*
-
+prst.*
+log.txt
# API-Key (keep secret at all times)
keys.py
diff --git a/bot/api/telegram.py b/bot/api/telegram.py
index bb6b96b..38e3425 100644
--- a/bot/api/telegram.py
+++ b/bot/api/telegram.py
@@ -1,23 +1,21 @@
import emoji
import requests
-import Levenshtein as lev
import datetime
import bot.api.keys
class TelegramIO():
- def __init__(self, persistence, commands):
+ def __init__(self, persistence):
"""Inits the Telegram-Interface
"""
self.base_url = "https://api.telegram.org/bot" + bot.api.keys.telegram_api + "/"
self.persistence = persistence
- self.commands = commands
# Dynamic variables for answering
self.chat_id = ""
self.offset = 0
self.message_id = ""
-
+ self.message_queue = []
def update_commands(self,commands):
@@ -35,38 +33,37 @@ class TelegramIO():
try:
result = requests.post(update_url,data=data)
result = result.json()["result"]
+ self.message_queue = result
except:
- result = ""
+ result = []
- return result
+ return len(result)
- def handle_result(self, result):
- """Inspects the message and reacts accordingly. Can easily be extended"""
- message_data = result[0]
+ def process_message(self):
+ """Inspects the first message from self.message_queue and reacts accordingly."""
+ message_data = self.message_queue.pop(0)
self.persistence["bot"]["messages_read"] += 1
self.offset = message_data["update_id"] + 1
if "edited_message" in message_data:
- return "nothing", "happened"
+ return
message = message_data["message"]
self.message_id = message["message_id"]
self.chat_id = message["chat"]["id"]
author = message["from"]
- chat_members = self.persistence["bot"]["chat_members"]
- if str(author["id"]) not in chat_members:
+ if author["id"] not in self.persistence["bot"]["chat_members"]:
name = ""
if "first_name" in author:
name += author["first_name"] + " "
if "last_name" in author:
name += author["last_name"]
if len(name) == 0:
- name += "anonymous"
- chat_members[author["id"]] = name
- self.persistence["bot"]["chat_members"] = chat_members
+ name = "anonymous"
+ self.persistence["bot"]["chat_members"][author["id"]] = name
self.send_message("Welcome to this chat " + name + "!")
if "text" in message:
@@ -75,45 +72,12 @@ class TelegramIO():
if "entities" in message:
for entry in message["entities"]:
if entry["type"] == "bot_command":
- return self.handle_command(message["text"][1:])
+ return message["text"] #self.handle_command(message["text"][1:])
elif "photo" in message:
print("Photo received, what do I do?")
- return "nothing", "happened"
-
-
- def handle_command(self, command):
- """Handles commands and stuff, using a bash-like syntax:
- /[command] [argument 1] [argument 2] ...
- """
- full = command.split(" ")
- command = self.fuzzy_match_command(full[0])
- if len(command) != 1:
- if command[0] == "EXACT":
- self.persistence["bot"]["commands_executed"] += 1
- return command[1], full[1:]
- else:
- send = "Did you mean " + command[1] + ""
- for i in range(2,len(command)):
- send += " or " + command[1] + ""
- send += "?"
- self.send_message(send)
- else:
- self.send_message("Command " + full[0] + " not found. Please try again.")
-
- return "nothing", ["happened"]
-
-
- def fuzzy_match_command(self, input):
- matches = ["not exact"]
- for command in self.commands.keys():
- if lev.ratio(input.lower(),command) > 0.8:
- matches.append(command)
- if lev.ratio(input.lower(),command) == 1:
- return ["EXACT", command]
-
- return matches
+ return
def send_thinking_note(self):
@@ -154,7 +118,7 @@ class TelegramIO():
out += " @ " + "telegram.send_message"
out += " --> " + "did not send:\n" + message
self.persistence["bot"]["log"] += [out]
-
+
def send_photo(self, url, caption):
print("SENDING PHOTO: " + url)
diff --git a/bot/framework.py b/bot/framework.py
new file mode 100644
index 0000000..17fed77
--- /dev/null
+++ b/bot/framework.py
@@ -0,0 +1,138 @@
+import datetime
+from bot.api import telegram, google, weather, reddit
+import Levenshtein as lev
+
+class BotFramework():
+ """Main functionality for a bot """
+
+ def __init__(self, name, version, prst):
+ """Inits the Bot with a few conf. vars
+ Args: -> name:str - Name of the bot
+ -> version:str - Version number
+ -> prst:shelveObj - persistence
+ """
+
+ self.version = version
+ self.name = name
+
+ # Persistent variable
+ self.persistence = prst
+ # Uptime counter
+ self.start_time = datetime.datetime.now()
+
+ self.emoji_dict = {
+ "a" : ":regional_indicator_symbol_letter_a:",
+ "b" : ":regional_indicator_symbol_letter_b:",
+ "c" : ":regional_indicator_symbol_letter_c:",
+ "d" : ":regional_indicator_symbol_letter_d:",
+ "e" : ":regional_indicator_symbol_letter_e:",
+ "f" : ":regional_indicator_symbol_letter_f:",
+ "g" : ":regional_indicator_symbol_letter_g:",
+ "h" : ":regional_indicator_symbol_letter_h:",
+ "i" : ":regional_indicator_symbol_letter_i:",
+ "j" : ":regional_indicator_symbol_letter_j:",
+ "k" : ":regional_indicator_symbol_letter_k:",
+ "l" : ":regional_indicator_symbol_letter_l:",
+ "m" : ":regional_indicator_symbol_letter_m:",
+ "n" : ":regional_indicator_symbol_letter_n:",
+ "o" : ":regional_indicator_symbol_letter_o:",
+ "p" : ":regional_indicator_symbol_letter_p:",
+ "q" : ":regional_indicator_symbol_letter_q:",
+ "r" : ":regional_indicator_symbol_letter_r:",
+ "s" : ":regional_indicator_symbol_letter_s:",
+ "t" : ":regional_indicator_symbol_letter_t:",
+ "u" : ":regional_indicator_symbol_letter_u:",
+ "v" : ":regional_indicator_symbol_letter_v:",
+ "w" : ":regional_indicator_symbol_letter_w:",
+ "x" : ":regional_indicator_symbol_letter_x:",
+ "y" : ":regional_indicator_symbol_letter_y:",
+ "z" : ":regional_indicator_symbol_letter_z:",
+ "0" : ":keycap_digit_zero:",
+ "1" : ":keycap_digit_one:",
+ "2" : ":keycap_digit_two:",
+ "3" : ":keycap_digit_three:",
+ "4" : ":keycap_digit_four:",
+ "5" : ":keycap_digit_five:",
+ "6" : ":keycap_digit_six:",
+ "7" : ":keycap_digit_seven:",
+ "8" : ":keycap_digit_eight:",
+ "9" : ":keycap_digit_nine:",
+ }
+
+ self.telegram = telegram.TelegramIO(self.persistence)
+
+ def react_chats(self):
+ """Checks unanswered messages and answers them"""
+ num = self.telegram.fetch_updates()
+ for i in range(num):
+ self.react_command()
+
+
+ def react_command(self):
+ """Reacts if a new command is present
+
+ Returns command, params iff the command is a hardware-one (for the clock), else None"""
+ message = self.telegram.process_message()
+ if message == None:
+ return
+
+ message = message[1:] #remove first "/"
+ tmp = message.split(" ")
+ cmd = tmp[0]
+ params = tmp[1:]
+
+ def call_command(cmd, par):
+ result = self.commands[cmd](*par)
+ # *params means the list is unpacked and handed over as separate arguments.
+ self.telegram.send_message(result)
+
+ if self.is_command(cmd): # first word
+ call_command(cmd, params)
+ elif cmd in self.persistence["bot"]["aliases"]:
+ dealias = self.persistence["bot"]["aliases"][cmd].split(" ") # as a list
+ new_cmd = dealias[0]
+ params = dealias[1:] + params
+ self.telegram.send_message("Substituted " + cmd + " to " + self.persistence["bot"]["aliases"][cmd] + " and got:")
+ call_command(new_cmd, params)
+ else:
+ self.telegram.send_message("Command " + tmp[0] + " not found.")
+
+
+ def is_command(self, input):
+ """checks if we have a command. Returns true if yes and False if not
+
+ Also sends a mesage if close to an existing command
+ """
+ max_match = 0
+ command_candidate = ""
+ for command in self.commands.keys():
+ match = lev.ratio(input.lower(),command)
+ if match > 0.7 and match > max_match:
+ max_match = match
+ command_candidate = command
+ if max_match == 1:
+ return True
+ if max_match != 0:
+ self.telegram.send_message("Did you mean " + command_candidate + "")
+ return False
+
+
+ def emojify_word(self,word):
+ """"""
+ string_emoji = ""
+ for letter in word:
+ if letter in self.emoji_dict:
+ string_emoji += self.emoji_dict[letter.lower()]
+ else:
+ string_emoji += letter
+ return string_emoji
+
+
+ def write_bot_log(self, function_name, error_message):
+ """"""
+ out = datetime.datetime.now().strftime("%d.%m.%y - %H:%M")
+ out += " @ " + function_name
+ out += " --> " + error_message
+ self.persistence["bot"]["log"] += [out]
+
+
\ No newline at end of file
diff --git a/bot/main.py b/bot/main.py
index 612e608..c290d34 100644
--- a/bot/main.py
+++ b/bot/main.py
@@ -1,33 +1,27 @@
-# -*- coding: utf-8 -*-
-
from bot.api import telegram, google, weather, reddit
+import datetime
+
import requests
import time
import json
import datetime
import emoji
-class ChatBot():
+import bot.framework as FW
+
+class ChatBot(FW.BotFramework):
""""""
- def __init__(self, name, version, prst):
+ def __init__(self, name, version, prst, hw_commands):
"""Inits the Bot with a few conf. vars
Args: -> name:str - Name of the bot
-> version:str - Version number
-> prst:shelveObj - persistence
"""
-
- self.version = version
- self.name = name
-
- # Persistent variable
- self.persistence = prst
- # Uptime counter
- self.start_time = datetime.datetime.now()
- self.persistence["bot"]["reboots"] += 1
-
+ super().__init__(name, version, prst)
+
# Available commands. Must be manually updated!
- self.commands = {
+ self.commands = dict({
"help" : self.bot_show_help,
"status" : self.bot_print_status,
"log" : self.bot_print_log,
@@ -43,81 +37,10 @@ class ChatBot():
"meme" : self.bot_send_meme,
"news" : self.bot_send_news,
"list" : self.bot_list,
+ "alias" : self.bot_save_alias,
+ }, **hw_commands)
+ # concat bot_commands + hw-commands
- }
-
-
- self.emoji_dict = {
- "a" : ":regional_indicator_symbol_letter_a:",
- "b" : ":regional_indicator_symbol_letter_b:",
- "c" : ":regional_indicator_symbol_letter_c:",
- "d" : ":regional_indicator_symbol_letter_d:",
- "e" : ":regional_indicator_symbol_letter_e:",
- "f" : ":regional_indicator_symbol_letter_f:",
- "g" : ":regional_indicator_symbol_letter_g:",
- "h" : ":regional_indicator_symbol_letter_h:",
- "i" : ":regional_indicator_symbol_letter_i:",
- "j" : ":regional_indicator_symbol_letter_j:",
- "k" : ":regional_indicator_symbol_letter_k:",
- "l" : ":regional_indicator_symbol_letter_l:",
- "m" : ":regional_indicator_symbol_letter_m:",
- "n" : ":regional_indicator_symbol_letter_n:",
- "o" : ":regional_indicator_symbol_letter_o:",
- "p" : ":regional_indicator_symbol_letter_p:",
- "q" : ":regional_indicator_symbol_letter_q:",
- "r" : ":regional_indicator_symbol_letter_r:",
- "s" : ":regional_indicator_symbol_letter_s:",
- "t" : ":regional_indicator_symbol_letter_t:",
- "u" : ":regional_indicator_symbol_letter_u:",
- "v" : ":regional_indicator_symbol_letter_v:",
- "w" : ":regional_indicator_symbol_letter_w:",
- "x" : ":regional_indicator_symbol_letter_x:",
- "y" : ":regional_indicator_symbol_letter_y:",
- "z" : ":regional_indicator_symbol_letter_z:",
- "0" : ":keycap_digit_zero:",
- "1" : ":keycap_digit_one:",
- "2" : ":keycap_digit_two:",
- "3" : ":keycap_digit_three:",
- "4" : ":keycap_digit_four:",
- "5" : ":keycap_digit_five:",
- "6" : ":keycap_digit_six:",
- "7" : ":keycap_digit_seven:",
- "8" : ":keycap_digit_eight:",
- "9" : ":keycap_digit_nine:",
- }
-
- self.telegram = telegram.TelegramIO(self.persistence, self.commands)
-
- def add_commands(self, commands):
- """adds new commands to an existing list"""
- self.commands = {**self.commands, **commands}
- self.telegram.update_commands(self.commands)
-
-
- def react_command(self, command, params):
- """"""
- result = self.commands[command](*params)
- #*params means the list is unpacked and handed over as separate arguments.
- self.telegram.send_message(result)
-
-
- def emojify_word(self,word):
- """"""
- string_emoji = ""
- for letter in word:
- if letter in self.emoji_dict:
- string_emoji += self.emoji_dict[letter.lower()]
- else:
- string_emoji += letter
- return string_emoji
-
-
- def write_bot_log(self, function_name, error_message):
- """"""
- out = datetime.datetime.now().strftime("%d.%m.%y - %H:%M")
- out += " @ " + function_name
- out += " --> " + error_message
- self.persistence["bot"]["log"] += [out]
############################################################################
@@ -137,13 +60,14 @@ class ChatBot():
def bot_print_status(self, *args):
"""Prints the bots current status and relevant information"""
delta = str(datetime.datetime.now() - self.start_time)
+ message = "BeebBop, this is " + self.name + " (V." + self.version + ")\n"
try:
ip = requests.get('https://api.ipify.org').text
except:
ip = "not fetchable"
- message = "
Status: Running :green_circle:\n"
+ message += "Status: Running :green_circle:\n"
message += "Uptime: " + delta[:delta.rfind(".")] + "\n"
- message += "Reboots: " + str(self.persistence["bot"]["reboots"]) + "\n"
+ message += "Reboots: " + str(self.persistence["global"]["reboots"]) + "\n"
message += "IP-Adress: " + ip + "\n"
message += "Messages read: " + str(self.persistence["bot"]["messages_read"]) + "\n"
message += "Messages sent: " + str(self.persistence["bot"]["messages_sent"]) + "\n"
@@ -217,10 +141,22 @@ class ChatBot():
def bot_show_help(self, *args):
- """Shows a list of all commands and their description"""
+ """Show a help message.
+
+ Usage: help {keyword}
+ Keywords:
+ * no kw - list of all commands
+ * full - all commands and their docstring
+ * command-name - specific command and its docstring
+ """
description = False
- if "full" in args:
- description = True
+ if len(args) > 0:
+ if args[0] == "full":
+ description = True
+ elif args[0] in self.commands:
+ send_text = "" + args[0] + "\n"
+ send_text += "" + self.commands[args[0]].__doc__ + ""
+ return send_text
send_text = "BeebBop, this is " + self.name + " (V." + self.version + ")\n"
send_text += "Here is what I can do up to now: \n"
@@ -236,12 +172,16 @@ class ChatBot():
def bot_print_log(self, *args):
- """Shows an error-log, mostly of bad api-requests. Usage
- log clear - clears log
- log system - shows python output"""
+ """Show an error-log, mostly of bad api-requests.
+
+ Usage: log {keyword}
+ Keywords:
+ * clear - clears log
+ * system - shows python output
+ """
if "clear" in args:
- self.persistence.write("log",[])
+ self.persistence["bot"]["log"] = []
return "Log cleared"
elif "system" in args:
path="persistence/log.txt"
@@ -254,7 +194,7 @@ class ChatBot():
return "could not read File"
send_text = ""
- for event in self.persistence.read("log"):
+ for event in self.persistence["bot"]["log"]:
send_text += event + "\n"
if send_text == "":
send_text += "No errors up to now"
@@ -262,7 +202,13 @@ class ChatBot():
def bot_show_wikipedia(self, *args):
- """Shows the wikipedia entry for a given term"""
+ """Shows the wikipedia entry for a given term
+
+ Usage: wikipedia <language> <term>
+ Keywords:
+ * language - de, fr, en ...
+ * term - search term, can consist of multiple words
+ """
if len(args) == 0:
return "Please provide the first argument for language (de or fr or en or ...) and then your query"
args = list(args)
@@ -283,7 +229,12 @@ class ChatBot():
def bot_zvv(self, *args):
"""Uses the swiss travel api to return the best route between a start- and endpoint.
- usage: 'start' to 'finish'"""
+
+ Usage: zvv <start> 'to' <finish>
+ Keywords:
+ * start - start point (can be more than 1 word9
+ * end - end point
+ """
if len(args) < 3:
return "Please specify a start- and endpoint as well as a separator (the 'to')"
@@ -360,7 +311,12 @@ class ChatBot():
def bot_tell_joke(self, *args):
- """Tells you the top joke on r/jokes"""
+ """Tells you the top joke on r/jokes
+
+ Usage: joke {number}
+ Keywords:
+ * number - number of jokes
+ """
params_sorted = self.match_reddit_params(*args)
@@ -427,20 +383,33 @@ class ChatBot():
def bot_list(self, *args):
- """Shows and interacts with a list. Usage
- list <name> <action> {object}
- actions are: create, delete, print, clear, add, remove
- example:
- list new shopping : creates list name shopping
+ """Interacts with a list (like a shopping list eg.)
+
+ Usage list <name> <action> {object}
+ Keyword:
+ * name - name of list
+ * action - create, delete, all, print, clear, add, remove
+ * object - might not be needed: index to delete, or item to add
+
+ Example usage:
+ list create shopping : creates list name shopping
list shopping add bread : adds bread to the list
list shopping print
list shopping clear
+ list all
"""
output = ""
# args = list(args)
- if len(args) < 2:
+ if len(args) == 0:
return "Missing parameters"
try:
+ if args[0] == "all":
+ try:
+ return "Existing lists are: " + list(self.persistence["global"]["lists"].keys()).join(" ")
+ except:
+ return "No lists created."
+ if len(args) < 2:
+ return "Missing parameters"
if args[0] == "create":
lname = " ".join(args[1:])
self.persistence["global"]["lists"][lname] = []
@@ -454,6 +423,7 @@ class ChatBot():
act = args[1]
if act == "print":
sl = self.persistence["global"]["lists"][lname]
+ output += "Content of " + lname + ":\n"
for ind,thing in enumerate(sl):
output += str(ind+1) + ". " + thing + "\n"
elif act == "clear":
@@ -474,7 +444,48 @@ class ChatBot():
def bot_save_alias(self, *args):
"""Save a shortcut for special commands (+params)
- usage: /alias sa shopping add
- Means: /sa will now be treated as input /shopping add"""
- return "Does this look finished to you?"
\ No newline at end of file
+ Usage: alias <alias-name> {<alias-name> <command>}
+ Keywords:
+ * action - all, add, delete or clear (deleta all)
+ * alias-name - short name
+ * command - command to be executed, can contain arguments for the command
+ Example usage:
+ * alias sa list shopping add
+ * alias sp list shopping print
+ Means that '/sa ...' will now be treated as if typed '/list shopping add ...'
+ """
+ # args = list(args)
+ if len(args) == 0:
+ return "Missing parameters"
+ try:
+ if args[0] == "clear":
+ self.persistence["bot"]["aliases"] = {}
+ return "All aliases cleared"
+ elif args[0] == "all":
+ try:
+ output = "Existing aliases are:\n"
+ for j, k in self.persistence["bot"]["aliases"].items():
+ output += j + " -> " + k + "\n"
+ return output
+ except:
+ return "No aliases created."
+
+ if len(args) < 2:
+ return "Missing parameters"
+ if args[0] == "delete":
+ ak = args[1]
+ self.persistence["bot"]["aliases"].pop(ak, None) # no error if key doesnt exist
+ return "Deleted alias " + ak
+
+ if len(args) < 3:
+ return "Missing parameters"
+ if args[0] == "add":
+ ak = args[1]
+ cmd = " ".join(args[2:])
+ self.persistence["bot"]["aliases"][ak] = cmd
+ return "Created alias for " + ak
+
+ except:
+ return "Could not handle your request. Maybe check the keys?"
+ return "Bad input..."
diff --git a/clock/main.py b/clock/main.py
index 96f2f91..bae504e 100644
--- a/clock/main.py
+++ b/clock/main.py
@@ -13,6 +13,8 @@ class ClockFace(object):
"""Actual functions one might need for a clock"""
def __init__(self, text_speed=18, prst=""):
+ """"""
+ self.persistence = prst
self.IO = led.OutputHandler(32,16)
self.tspeed = text_speed
@@ -21,6 +23,12 @@ class ClockFace(object):
self.output_queue = []
# Threads to execute next
+ self.commands = {
+ "blink" : self.alarm_blink,
+ "wakeup" : self.wake_light,
+ "showmessage" : self.show_message,
+ }
+
self.weather = ""
self.brightness_overwrite = {"value" : 1, "duration" : 0}
@@ -82,6 +90,11 @@ class ClockFace(object):
############################################################################
### Higher level commands, accessible from the chat-bot
+ def external_action(self, command, params):
+ """"""
+ self.commands[command](*params)
+
+
def wake_light(self, duration=600):
"""Simulates a sunris, takes one optional parameter: the duration"""
def output(duration):
@@ -99,11 +112,10 @@ class ClockFace(object):
self.IO.set_matrix(ones,colors=[col])
time.sleep(int(duration) / 20)
-
self.run(output,(duration,))
- def alarm_blink(self, duration, frequency):
+ def alarm_blink(self, duration=0, frequency=0):
"""Blinks the whole screen (red-black). Duration in seconds, frequency in Hertz"""
def output(duration, frequency):
self.set_brightness(value=1)
@@ -118,8 +130,8 @@ class ClockFace(object):
time.sleep(1/frequency)
self.IO.set_matrix(empty)
time.sleep(1/frequency)
-
- self.run(output,(duration, frequency))
+ if not(duration == 0 or frequency == 0):
+ self.run(output,(duration, frequency))
def image_show(self, image, duration):
diff --git a/dashboard_wrapper.py b/dashboard_wrapper.py
deleted file mode 100644
index 42a38c7..0000000
--- a/dashboard_wrapper.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import wrapper
-
-from threading import Thread
-import time
-
-class DashBoardWrapper(wrapper.Wrapper):
- def __init__(self, own_module, *other_modules):
- """"""
- super().__init__(own_module, other_modules)
- print("Initializing DASHBOARD-functionality")
- # mainloop
-
- def mainloop(self):
- super(DashBoardWrapper, self).mainloop(sleep_delta = 3600*3) #3hours refresh-cycle
- self.set_weather()
- self.set_shopping_list()
- self.set_bot_logs()
- self.set_joke()
- self.bot.refresh()
-
- def set_weather(self):
- weather = self.bot.bot_show_weather("zurich")
- ...
- self.own.set_weather(weather)
diff --git a/launcher.py b/launcher.py
index fc30143..d6ec187 100644
--- a/launcher.py
+++ b/launcher.py
@@ -2,7 +2,6 @@
import bot.main
import clock.main
import dashboard.main
-
# wrapper
import wrapper
@@ -10,18 +9,18 @@ import wrapper
from threading import Thread
import shelve
-
class Launcher():
"""Launches all other submodules"""
def __init__(self):
""""""
- self.persistence = shelve.open('persistence/prst.db', writeback=True)
- self.init_persistence()
- # TODO populate the persistence
- self.bot_module = bot.main.ChatBot(name="ChatterBot", version="2.1", prst=self.persistence)
+ self.persistence = shelve.DbfilenameShelf("persistence/prst.db", writeback = True)
+ if len(self.persistence) == 0:
+ self.init_persistence()
+ self.persistence["global"]["reboots"] += 1
self.clock_module = clock.main.ClockFace(prst=self.persistence)
-
+ self.bot_module = bot.main.ChatBot(name="ChatterBot", version="2.1", prst=self.persistence, hw_commands=self.clock_module.commands)
+
self.threads = []
self.threads.append(Thread(target=self.chatbot))
self.threads.append(Thread(target=self.clock))
@@ -42,6 +41,7 @@ class Launcher():
self.dashboard = wrapper.DashBoardWrapper(self.dashboard_module, self.bot_module)
def init_persistence(self):
+ print("New Persistence created")
self.persistence["bot"] = {
"messages_read": 0,
"messages_sent": 0,
@@ -49,15 +49,16 @@ class Launcher():
"photos_sent": 0,
"log": [],
"chat_members": {},
- "reboots": 0
+ "aliases" : {}
}
self.persistence["clock"] = {}
self.persistence["dashboard"] = {}
self.persistence["global"] = {
- "lists" : {}
+ "lists" : {},
+ "reboots": 0
}
########################################################################
## Aand liftoff!
-Launcher()
+Launcher()
\ No newline at end of file
diff --git a/persistence/__init__.py b/persistence/__init__.py
new file mode 100644
index 0000000..fc6bb0e
--- /dev/null
+++ b/persistence/__init__.py
@@ -0,0 +1 @@
+#placeholder
\ No newline at end of file
diff --git a/wrapper.py b/wrapper.py
index 1cda615..fcdc268 100644
--- a/wrapper.py
+++ b/wrapper.py
@@ -19,6 +19,8 @@ class Wrapper():
while True:
action()
time.sleep(sleep_delta)
+ self.own.persistence.sync()
+
@@ -86,16 +88,6 @@ class BotWrapper(Wrapper):
self.bot = own_module
self.clock = other_modules[0]
-
-
- # available hw-commands. Must be updated manually!
- self.hw_commands = {
- "blink" : self.clock.alarm_blink,
- "wakeup" : self.clock.wake_light,
- "showmessage" : self.clock.show_message,
-
- }
- self.bot.add_commands(self.hw_commands)
self.mainloop(10)
@@ -103,18 +95,38 @@ class BotWrapper(Wrapper):
def mainloop(self, sleep_delta):
"""Calls the telegram entity regularly to check for activity"""
def perform_loop():
- result = self.bot.telegram.fetch_updates()
- if len(result) != 0:
- command, params = self.bot.telegram.handle_result(result)
- if command != "nothing":
- if command in self.hw_commands:
- self.react_hw_command(command,params) # hw-level
- else:
- self.bot.react_command(command,params) # sw-level
+ self.bot.react_chats()
+ # num = self.bot.telegram.fetch_updates()
+ # for message in range(num):
+ # command, params = self.bot.react_command() # returns None if handled internally
+ # if command != None:
+ # self.clock.external_action(command, params)
+ super().mainloop(sleep_delta, perform_loop)
+
+
+
+
+from threading import Thread
+
+class DashBoardWrapper(Wrapper):
+ def __init__(self, own_module, *other_modules):
+ """Wrapper for the dashboard functionality"""
+ super().__init__(own_module, other_modules)
+ # self.mainloop(2 * 3600) # 2 hours refresh-cycle
+
+
+ def mainloop(self, sleep_delta):
+ def perform_loop():
+ self.set_weather()
+ self.set_shopping_list()
+ self.set_bot_logs()
+ self.set_joke()
+ self.bot.refresh()
super().mainloop(sleep_delta, perform_loop)
- def react_hw_command(self, command, params):
- """"""
- # so params is a list, and so, to pass the commands, we need to unpack it:
- self.hw_commands[command](*params)
+
+ def set_weather(self):
+ weather = self.bot.bot_show_weather("zurich")
+ ...
+ self.own.set_weather(weather)