Adjusted bot functions for new backend
This commit is contained in:
		| @@ -6,7 +6,8 @@ logger = logging.getLogger(__name__) | ||||
| class WeatherFetch(): | ||||
|     def __init__(self, key): | ||||
|         self.last_fetch = datetime.datetime.fromtimestamp(0) | ||||
|         self.last_weather = "" | ||||
|         self.last_fetch_location = [] | ||||
|         self.last_weather = [] | ||||
|         self.calls = 0 | ||||
|  | ||||
|         self.url = "https://api.openweathermap.org/data/2.5/onecall?" | ||||
| @@ -14,8 +15,10 @@ class WeatherFetch(): | ||||
|  | ||||
|     def show_weather(self, location): | ||||
|         delta = datetime.datetime.now() - self.last_fetch | ||||
|         if delta.total_seconds()/60 > 60 or "\n" not in self.last_weather: # 1 hour passed: | ||||
|  | ||||
|          # 1 hour passed, error, or location change | ||||
|         if delta.total_seconds() > 3600 \ | ||||
|             or len(self.last_weather) == 0\ | ||||
|             or self.last_fetch_location != location: | ||||
|              | ||||
|             data = {"lat" : location[0], "lon" : location[1], "exclude" : "minutely,hourly", "appid" : self.key, "units" : "metric"} | ||||
|             self.calls += 1 | ||||
| @@ -35,11 +38,12 @@ class WeatherFetch(): | ||||
|                         "short" : day["weather"][0]["main"], | ||||
|                         "temps" : [int(day["temp"]["min"]),int(day["temp"]["max"])] | ||||
|                         }) | ||||
|              | ||||
|                 self.last_fetch_location = location | ||||
|                 self.last_weather = ret_weather | ||||
|                 self.last_fetch = datetime.datetime.now() | ||||
|             except: | ||||
|                 ret_weather = [] | ||||
|  | ||||
|             self.last_weather = ret_weather | ||||
|             self.last_fetch = datetime.datetime.now() | ||||
|         else: | ||||
|             ret_weather = self.last_weather | ||||
|  | ||||
|   | ||||
| @@ -6,9 +6,10 @@ NAME, NEW, ACTION, ITEMADD, ITEMREMOVE = range(5) | ||||
| class Lists(BotFunc): | ||||
|     """Create and edit lists""" | ||||
|  | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|     def __init__(self, db_utils): | ||||
|         super().__init__(db_utils) | ||||
|         self.current_name = "" | ||||
|         # self.db_utils set through super() | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
| @@ -38,10 +39,8 @@ class Lists(BotFunc): | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         # TODO Change DB | ||||
|         lists = self.db.lists.select() | ||||
|         sl = [l.name for l in lists] | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data="list-"+k)] for k in sl] + [[InlineKeyboardButton("New list", callback_data="new")]] | ||||
|         lists = self.db_utils.list_get() | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data="list-"+k)] for k in lists] + [[InlineKeyboardButton("New list", callback_data="new")]] | ||||
|  | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=False, send=True) | ||||
| @@ -96,12 +95,12 @@ class Lists(BotFunc): | ||||
|     def new_listname(self, update: Update, context: CallbackContext) -> None: | ||||
|         name = update.message.text | ||||
|         try: | ||||
|             data = self.db.lists(name=name, content="") | ||||
|             data.save() | ||||
|             self.db_utils.list_create(name) | ||||
|             keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("To the menu!", callback_data="overview")]] | ||||
|             reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|             self.current_name = name | ||||
|             update.message.reply_text("Thanks. List " + name + " was successfully created.", reply_markup=reply_markup) | ||||
|             super().log_activity(read=False, execute=True, send=True) | ||||
|             return ACTION | ||||
|         except Exception as e: | ||||
|             update.message.reply_text("Oh no! Encountered exception: {}".format(e)) | ||||
| @@ -118,8 +117,7 @@ class Lists(BotFunc): | ||||
|     def list_remove(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         it = self.db.lists.get(self.db.lists.name == self.current_name) | ||||
|         sl = it.content.split("<-->") | ||||
|         sl = self.db_utils.list_get(self.current_name) | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data=i)] for i,k in enumerate(sl)] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
| @@ -131,7 +129,7 @@ class Lists(BotFunc): | ||||
|     def list_clear(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         self.db.lists.update(content="").where(self.db.lists.name == self.current_name).execute() | ||||
|         self.db_utils.list_update(self.current_name, replace=[]) | ||||
|         keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text("List " + self.current_name + " cleared", reply_markup=reply_markup) | ||||
| @@ -141,7 +139,7 @@ class Lists(BotFunc): | ||||
|     def list_delete(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         self.db.lists.delete().where(self.db.lists.name == self.current_name).execute() | ||||
|         self.db_utils.list_delete(self.current_name) | ||||
|         query.edit_message_text("List " + self.current_name + " deleted") | ||||
|         return ConversationHandler.END | ||||
|  | ||||
| @@ -149,10 +147,9 @@ class Lists(BotFunc): | ||||
|     def list_print(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         it = self.db.lists.get(self.db.lists.name == self.current_name) | ||||
|         it = self.db_utils.list_get(self.current_name) | ||||
|         if it: | ||||
|             content = it.content.split("<-->") | ||||
|             content = "\n".join(content) | ||||
|             content = "\n".join(it) | ||||
|         else: | ||||
|             content = "List empty" | ||||
|          | ||||
| @@ -164,14 +161,7 @@ class Lists(BotFunc): | ||||
|  | ||||
|     def list_add_item(self, update: Update, context: CallbackContext) -> None: | ||||
|         item = update.message.text | ||||
|         it = self.db.lists.get(self.db.lists.name == self.current_name) | ||||
|         if it: | ||||
|             sl = it.content | ||||
|         else: | ||||
|             sl = "" | ||||
|         sl += item + "<-->" | ||||
|         self.db.lists.update(content=sl).where(self.db.lists.name == self.current_name).execute() | ||||
|  | ||||
|         self.db_utils.list_update(self.current_name, append=item) | ||||
|         keyboard = [[InlineKeyboardButton("Add some more", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         update.message.reply_text("Added " + item, reply_markup=reply_markup) | ||||
| @@ -183,13 +173,9 @@ class Lists(BotFunc): | ||||
|         ind = int(query.data) | ||||
|         query.answer() | ||||
|  | ||||
|         it = self.db.lists.get(self.db.lists.name == self.current_name) | ||||
|         old = it.content.split("<-->") | ||||
|         # todo make better | ||||
|  | ||||
|         old = self.db_utils.list_get(self.current_name) | ||||
|         name = old.pop(ind) | ||||
|         new = "<-->".join(old) | ||||
|         self.db.lists.update(content=new).where(self.db.lists.name == self.current_name).execute() | ||||
|         self.db_utils.list_update(self.current_name, replace=old) | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton("Remove another", callback_data="remove"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard)       | ||||
|   | ||||
| @@ -3,8 +3,8 @@ from .template import * | ||||
|  | ||||
| class Plain(BotFunc): | ||||
|     """Not a command: just keeps logs and usage_data""" | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|     def __init__(self, db_utils): | ||||
|         super().__init__(db_utils) | ||||
|      | ||||
|     def create_handler(self): | ||||
|         h = MessageHandler(Filters.text, callback=self.add_to_log) | ||||
|   | ||||
| @@ -3,8 +3,6 @@ from .template import * | ||||
| import datetime | ||||
| import requests | ||||
| import socket | ||||
| import numpy as np | ||||
| import os | ||||
| import json | ||||
|  | ||||
|  | ||||
| @@ -13,8 +11,8 @@ FIRST = 1 | ||||
| class Status(BotFunc): | ||||
|     """Shows a short status of the program.""" | ||||
|      | ||||
|     def __init__(self, name, version, db): | ||||
|         super().__init__(db) | ||||
|     def __init__(self, name, version, db_utils): | ||||
|         super().__init__(db_utils) | ||||
|         self.start_time = datetime.datetime.now() | ||||
|         self.name = name | ||||
|         self.version = version | ||||
| @@ -63,13 +61,13 @@ class Status(BotFunc): | ||||
|         message += "URL: [" + u + "](" + u + ")\n" | ||||
|          | ||||
|         # TODO new DB | ||||
|         tot_r = self.db.chats.select().where(self.db.chats.read == True).count() | ||||
|         tot_r = self.db_utils.chat_count("read") | ||||
|         message += "Total messages read: `{}`\n".format(tot_r) | ||||
|  | ||||
|         tot_s = self.db.chats.select().where(self.db.chats.send == True).count() | ||||
|         tot_s = self.db_utils.chat_count("send") | ||||
|         message += "Total messages sent: `{}`\n".format(tot_s) | ||||
|  | ||||
|         tot_e = self.db.chats.select().where(self.db.chats.execute == True).count() | ||||
|         tot_e = self.db_utils.chat_count("execute") | ||||
|         message += "Total commands executed: `{}`\n".format(tot_e) | ||||
|  | ||||
|         if update.message: | ||||
| @@ -101,6 +99,5 @@ class Status(BotFunc): | ||||
|             for i in res_json["tunnels"]: | ||||
|                 if i['name'] == 'command_line': | ||||
|                     return i['public_url'] | ||||
|                     break | ||||
|         except: | ||||
|             return "Not available" | ||||
| @@ -15,25 +15,13 @@ import datetime | ||||
|  | ||||
| class BotFunc(): | ||||
|     """Base class for a specific bot-functionality""" | ||||
|     def __init__(self, db): | ||||
|     def __init__(self, db_utils): | ||||
|         self.logger = logging.getLogger(__name__) | ||||
|         self.db = db | ||||
|         self.db_utils = db_utils | ||||
|  | ||||
|  | ||||
|     # def log_activity(self, **kwargs): | ||||
|     #     # mark that a new command has been executed | ||||
|     #     try: | ||||
|     #         data = self.db.chats( | ||||
|     #             time=datetime.datetime.now(), | ||||
|     #             **kwargs | ||||
|     #             ) | ||||
|     #         # kwargs can look like | ||||
|     #         # receive=True, | ||||
|     #         # execute=True, | ||||
|     #         # send=False, | ||||
|     #         data.save() | ||||
|     #     except Exception as e: | ||||
|     #         self.logger.error("sql error: {}".format(e)) | ||||
|     def log_activity(self, **kwargs): | ||||
|         # mark that a new command has been executed | ||||
|         self.db_utils.sensor_log(**kwargs) | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         if update.message.text: | ||||
|   | ||||
| @@ -75,7 +75,7 @@ class Weather(BotFunc): | ||||
|         forecast_time = query.data.replace("time-","") | ||||
|         weather = self.get_weather(self.city, forecast_time) | ||||
|         query.edit_message_text( | ||||
|             text = "Weather: \n\n" + weather, | ||||
|             text = "Broadcast for {}: \n\n{}".format(self.city, weather), | ||||
|             parse_mode = ParseMode.HTML | ||||
|         ) | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|   | ||||
| @@ -36,7 +36,7 @@ class ChatBot(): | ||||
|          | ||||
|     def add_commands(self): | ||||
|         # Mark modules as available | ||||
|         db = self.db | ||||
|         db = self.db_utils | ||||
|         self.help_module = self.commands.help.Help(db) | ||||
|         self.sub_modules = { | ||||
|             "weather": self.commands.weather.Weather(self.api_weather, db), | ||||
| @@ -60,7 +60,7 @@ class ChatBot(): | ||||
|         self.help_module.add_commands(self.sub_modules) | ||||
|     	 | ||||
|     def start(self): | ||||
|         self.sub_modules = {"clock" : self.commands.clock.Clock(self.db, self.modules["clock"], self.api_art)} | ||||
|         self.sub_modules = {"clock" : self.commands.clock.Clock(self.db_utils, self.modules["clock"], self.api_art)} | ||||
|         self.add_commands() | ||||
|         self.telegram.start_polling( | ||||
|             poll_interval=0.2, | ||||
|   | ||||
| @@ -22,19 +22,17 @@ db_connection = PooledMySQLDatabase( | ||||
| ) | ||||
|  | ||||
|  | ||||
| def auto_connect_db(action): | ||||
|     def decorated(func): | ||||
|         def wrapper(*args, **kwargs): | ||||
|             #before: | ||||
|             db_connection.connect() | ||||
|             ret = func(*args, **kwargs) | ||||
|             #after: | ||||
|             db_connection.close() | ||||
|             # also, action is in scope now | ||||
|             return ret | ||||
| def auto_connect_db(func): | ||||
|     def wrapper(*args, **kwargs): | ||||
|         #before: | ||||
|         db_connection.connect() | ||||
|         ret = func(*args, **kwargs) | ||||
|         #after: | ||||
|         db_connection.close() | ||||
|         # also, action is in scope now | ||||
|         return ret | ||||
|      | ||||
|         return wrapper | ||||
|     return decorated | ||||
|     return wrapper | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -57,20 +55,21 @@ class DatabaseUtils: | ||||
|         else: # does not exist | ||||
|             return -1 | ||||
|  | ||||
|  | ||||
|     @auto_connect_db | ||||
|     def chat_log(self, **kwargs): | ||||
|         models.ChatMetric(**kwargs) | ||||
|  | ||||
|  | ||||
|     @auto_connect_db | ||||
|     def list_get(self, list_name=""): | ||||
|         if not list_name: # return all | ||||
|             return models.List.select() | ||||
|             cursor = models.List.select(models.List.name).execute() | ||||
|             return [k.name for k in cursor] | ||||
|         else: | ||||
|             return models.List.get(models.List.name == list_name) | ||||
|             return models.List.get(models.List.name == list_name).content_as_list | ||||
|          | ||||
|      | ||||
|     def list_update(self, list_name, append="", replace=[]): | ||||
|         if replace: | ||||
|     @auto_connect_db     | ||||
|     def list_update(self, list_name, append="", replace=None): | ||||
|         if replace != None: | ||||
|             models.List.get(models.List.name == list_name).set_content(replace) | ||||
|         elif append: | ||||
|             l_obj = models.List.get(models.List.name == list_name) | ||||
| @@ -80,9 +79,14 @@ class DatabaseUtils: | ||||
|         else: | ||||
|             logger.warning("Empty update_list() query was made. Ignoring") | ||||
|  | ||||
|     @auto_connect_db | ||||
|     def list_create(self, list_name): | ||||
|         models.List(name=list_name).save() | ||||
|  | ||||
|     @auto_connect_db | ||||
|     def list_delete(self, list_name): | ||||
|         models.List.delete().where(self.db.lists.name == list_name).execute() | ||||
|         models.List.delete().where(models.List.name == list_name).execute() | ||||
|  | ||||
|     @auto_connect_db | ||||
|     def sensor_log(self, **kwargs): | ||||
|         models.SensorMetric(**kwargs).save() | ||||
| @@ -45,11 +45,12 @@ class ErrorMetric(Metric): | ||||
|  | ||||
| class List(DBModel): | ||||
|     name = CharField(unique=True) | ||||
|     content = TextField() # unlimited length, use to serialise list into | ||||
|     content = TextField(default="") # unlimited length, use to serialise list into | ||||
|  | ||||
|     @property | ||||
|     def content_as_list(self): | ||||
|         return json.loads(self.content) | ||||
|         return json.loads(self.content or '[]') | ||||
|      | ||||
|     def set_content(self, list_content): | ||||
|         self.content = json.dumps(list_content) | ||||
|         self.save() | ||||
							
								
								
									
										34
									
								
								req_pi.txt
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								req_pi.txt
									
									
									
									
									
								
							| @@ -1,17 +1,17 @@ | ||||
| Adafruit-Blinka==6.10.3 | ||||
| adafruit-circuitpython-dht==3.6.1 | ||||
| Adafruit-PlatformDetect==3.14.2 | ||||
| Adafruit-PureIO==1.1.9 | ||||
| board==1.0 | ||||
| importlib-metadata==4.6.0 | ||||
| pkg-resources==0.0.0 | ||||
| psycopg2==2.9.1 | ||||
| psycopg2-binary==2.9.1 | ||||
| pyftdi==0.53.1 | ||||
| pyserial==3.5 | ||||
| pyusb==1.1.1 | ||||
| rpi-ws281x==4.3.0 | ||||
| RPi.GPIO==0.7.0 | ||||
| sysv-ipc==1.1.0 | ||||
| typing-extensions==3.10.0.0 | ||||
| zipp==3.4.1 | ||||
| Adafruit-Blinka>=6.10.3 | ||||
| adafruit-circuitpython-dht>=3.6.1 | ||||
| Adafruit-PlatformDetect>=3.14.2 | ||||
| Adafruit-PureIO>=1.1.9 | ||||
| board>=1.0 | ||||
| importlib-metadata>=4.6.0 | ||||
| pkg-resources>=0.0.0 | ||||
| psycopg2>=2.9.1 | ||||
| psycopg2-binary>=2.9.1 | ||||
| pyftdi>=0.53.1 | ||||
| pyserial>=3.5 | ||||
| pyusb>=1.1.1 | ||||
| rpi-ws281x>=4.3.0 | ||||
| RPi.GPIO>=0.7.0 | ||||
| sysv-ipc>=1.1.0 | ||||
| typing-extensions>=3.10.0.0 | ||||
| zipp>=3.4.1 | ||||
| @@ -28,7 +28,7 @@ class BroadcastLauncher(launcher.Launcher): | ||||
|     """Launcher for all server-side modules. The hard-computations""" | ||||
|     def __init__(self): | ||||
|          | ||||
|         self.bot_module = main.ChatBot(name="Norbit", version="4.0a") # ???  | ||||
|         self.bot_module = main.ChatBot(name="Norbit", version="4.1a") # ???  | ||||
|         self.clock_backend_module = c_back.ClockBackend() # threaded through threading.Timer | ||||
|         self.broadcast_module = b_out.BroadcastUpdates(port="1111") # Thread | ||||
|         # self.dashboard_module = d_out.DashBoard(port="80") # ??? threaded as Thread | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Remy Moll
					Remy Moll