t
This commit is contained in:
		| @@ -1 +1 @@ | ||||
| # Placeholder | ||||
| # Placeholder | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| from . import keys | ||||
| from . import reddit | ||||
| from . import weather | ||||
| from . import reddit | ||||
| from . import search | ||||
| from . import keys | ||||
| from . import reddit | ||||
| from . import weather | ||||
| from . import reddit | ||||
| from . import search | ||||
| from . import metmuseum | ||||
| @@ -1,39 +1,39 @@ | ||||
| import requests | ||||
| import random | ||||
| from PIL import Image | ||||
| import io | ||||
|  | ||||
| class ArtFetch: | ||||
|     def __init__(self): | ||||
|         self.base_url = "https://collectionapi.metmuseum.org/" | ||||
|         self.objects = self.fetch_objects() # chosen set of images to select randomly | ||||
|          | ||||
|  | ||||
|     def fetch_objects(self): | ||||
|         """We restrict ourselves to a few domains.""" | ||||
|         # fetch all departements | ||||
|         t = requests.get(self.base_url + "public/collection/v1/departments").json() | ||||
|         deps = t["departments"] | ||||
|         keep_id = [] | ||||
|         for d in deps: | ||||
|             name = d["displayName"] | ||||
|             if name == "American Decorative Arts" or name == "Arts of Africa, Oceania, and the Americas" or name == "Asian Art" or name == "European Paintings": | ||||
|                 keep_id.append(str(d["departmentId"])) | ||||
|         # fetch artworks listed under these departments | ||||
|         data = {"departmentIds" : "|".join(keep_id)} | ||||
|         t = requests.get(self.base_url + "public/collection/v1/objects",params=data).json() | ||||
|         # num = t["total"] | ||||
|         ids = t["objectIDs"] | ||||
|         return ids | ||||
|  | ||||
|     def get_random_art(self): | ||||
|         """Returns an image object of a randomly selected artwork""" | ||||
|         # fetch the artwork's url | ||||
|         r_id = self.objects[random.randint(0,len(self.objects))] | ||||
|         t = requests.get(self.base_url + "public/collection/v1/objects/" + str(r_id)).json() | ||||
|         im_url = t["primaryImageSmall"] | ||||
|         # download the image | ||||
|         resp = requests.get(im_url) | ||||
|         img = Image.open(io.BytesIO(resp.content)) | ||||
|  | ||||
|         return img | ||||
| import requests | ||||
| import random | ||||
| from PIL import Image | ||||
| import io | ||||
|  | ||||
| class ArtFetch: | ||||
|     def __init__(self): | ||||
|         self.base_url = "https://collectionapi.metmuseum.org/" | ||||
|         self.objects = self.fetch_objects() # chosen set of images to select randomly | ||||
|          | ||||
|  | ||||
|     def fetch_objects(self): | ||||
|         """We restrict ourselves to a few domains.""" | ||||
|         # fetch all departements | ||||
|         t = requests.get(self.base_url + "public/collection/v1/departments").json() | ||||
|         deps = t["departments"] | ||||
|         keep_id = [] | ||||
|         for d in deps: | ||||
|             name = d["displayName"] | ||||
|             if name == "American Decorative Arts" or name == "Arts of Africa, Oceania, and the Americas" or name == "Asian Art" or name == "European Paintings": | ||||
|                 keep_id.append(str(d["departmentId"])) | ||||
|         # fetch artworks listed under these departments | ||||
|         data = {"departmentIds" : "|".join(keep_id)} | ||||
|         t = requests.get(self.base_url + "public/collection/v1/objects",params=data).json() | ||||
|         # num = t["total"] | ||||
|         ids = t["objectIDs"] | ||||
|         return ids | ||||
|  | ||||
|     def get_random_art(self): | ||||
|         """Returns an image object of a randomly selected artwork""" | ||||
|         # fetch the artwork's url | ||||
|         r_id = self.objects[random.randint(0,len(self.objects))] | ||||
|         t = requests.get(self.base_url + "public/collection/v1/objects/" + str(r_id)).json() | ||||
|         im_url = t["primaryImageSmall"] | ||||
|         # download the image | ||||
|         resp = requests.get(im_url) | ||||
|         img = Image.open(io.BytesIO(resp.content)) | ||||
|  | ||||
|         return img | ||||
|   | ||||
| @@ -1,56 +1,56 @@ | ||||
| import praw | ||||
|  | ||||
|  | ||||
|  | ||||
| class RedditFetch(): | ||||
|     def __init__(self, key): | ||||
|         self.stream = praw.Reddit(client_id = key["id"], client_secret = key["secret"], user_agent=key["user_agent"]) | ||||
|  | ||||
|     def get_top(self, subreddit, number, return_type="text"): | ||||
|         if return_type == "text": | ||||
|             posts = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).top(limit=number): | ||||
|                     p = {} | ||||
|                     if not submission.stickied: | ||||
|                         p["title"] = submission.title | ||||
|                         p["content"] = submission.selftext | ||||
|                         posts.append(p) | ||||
|                 return posts | ||||
|             except: | ||||
|                 return [] | ||||
|         else: | ||||
|             images = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).top(limit=number): | ||||
|                     if not submission.stickied: | ||||
|                         t = {"image": submission.url, "caption": submission.title} | ||||
|                         images.append(t) | ||||
|                 return images | ||||
|             except: | ||||
|                 return [] | ||||
|  | ||||
|  | ||||
|     def get_random_rising(self, subreddit, number, return_type="text"): | ||||
|         if return_type == "text": | ||||
|             posts = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).random_rising(limit=number): | ||||
|                     p = {} | ||||
|                     if not submission.stickied: | ||||
|                         p["title"] = submission.title | ||||
|                         p["content"] = submission.selftext | ||||
|                         posts.append(p) | ||||
|                 return posts | ||||
|             except: | ||||
|                 return [] | ||||
|         else: | ||||
|             images = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).random_rising(limit=number): | ||||
|                     if not submission.stickied: | ||||
|                         t = {"image": submission.url, "caption": submission.title} | ||||
|                         images.append(t) | ||||
|                 return images | ||||
|             except: | ||||
|                 return [] | ||||
| import praw | ||||
|  | ||||
|  | ||||
|  | ||||
| class RedditFetch(): | ||||
|     def __init__(self, key): | ||||
|         self.stream = praw.Reddit(client_id = key["id"], client_secret = key["secret"], user_agent=key["user_agent"]) | ||||
|  | ||||
|     def get_top(self, subreddit, number, return_type="text"): | ||||
|         if return_type == "text": | ||||
|             posts = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).top(limit=number): | ||||
|                     p = {} | ||||
|                     if not submission.stickied: | ||||
|                         p["title"] = submission.title | ||||
|                         p["content"] = submission.selftext | ||||
|                         posts.append(p) | ||||
|                 return posts | ||||
|             except: | ||||
|                 return [] | ||||
|         else: | ||||
|             images = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).top(limit=number): | ||||
|                     if not submission.stickied: | ||||
|                         t = {"image": submission.url, "caption": submission.title} | ||||
|                         images.append(t) | ||||
|                 return images | ||||
|             except: | ||||
|                 return [] | ||||
|  | ||||
|  | ||||
|     def get_random_rising(self, subreddit, number, return_type="text"): | ||||
|         if return_type == "text": | ||||
|             posts = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).random_rising(limit=number): | ||||
|                     p = {} | ||||
|                     if not submission.stickied: | ||||
|                         p["title"] = submission.title | ||||
|                         p["content"] = submission.selftext | ||||
|                         posts.append(p) | ||||
|                 return posts | ||||
|             except: | ||||
|                 return [] | ||||
|         else: | ||||
|             images = [] | ||||
|             try: | ||||
|                 for submission in self.stream.subreddit(subreddit).random_rising(limit=number): | ||||
|                     if not submission.stickied: | ||||
|                         t = {"image": submission.url, "caption": submission.title} | ||||
|                         images.append(t) | ||||
|                 return images | ||||
|             except: | ||||
|                 return [] | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
| import duckduckpy | ||||
|  | ||||
| class WebSearch(): | ||||
|     def __init__(self): | ||||
|         self.search = duckduckpy.query | ||||
|  | ||||
|     def get_result(self, query): | ||||
|         try: | ||||
|             res = [] | ||||
|             response = self.search(query, container = "dict")["related_topics"] | ||||
|             for r in response: | ||||
|                 if "text" in r: | ||||
|                     res.append({ | ||||
|                         "text" : r["text"], | ||||
|                         "url": r["first_url"] | ||||
|                         }) | ||||
|         except: | ||||
|             res = ["Connection error"] | ||||
|         return res | ||||
|  | ||||
| import duckduckpy | ||||
|  | ||||
| class WebSearch(): | ||||
|     def __init__(self): | ||||
|         self.search = duckduckpy.query | ||||
|  | ||||
|     def get_result(self, query): | ||||
|         try: | ||||
|             res = [] | ||||
|             response = self.search(query, container = "dict")["related_topics"] | ||||
|             for r in response: | ||||
|                 if "text" in r: | ||||
|                     res.append({ | ||||
|                         "text" : r["text"], | ||||
|                         "url": r["first_url"] | ||||
|                         }) | ||||
|         except: | ||||
|             res = ["Connection error"] | ||||
|         return res | ||||
|  | ||||
| # TODO: this api has more potential. Extract images or quick facts! | ||||
| @@ -1,87 +1,87 @@ | ||||
| import requests | ||||
| import datetime | ||||
|  | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
| class WeatherFetch(): | ||||
|     def __init__(self, key): | ||||
|         self.last_fetch = datetime.datetime.fromtimestamp(0) | ||||
|         self.last_weather = "" | ||||
|         self.calls = 0 | ||||
|  | ||||
|         self.url = "https://api.openweathermap.org/data/2.5/onecall?" | ||||
|         self.key = key | ||||
|  | ||||
|     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: | ||||
|  | ||||
|              | ||||
|             data = {"lat" : location[0], "lon" : location[1], "exclude" : "minutely,hourly", "appid" : self.key, "units" : "metric"} | ||||
|             self.calls += 1 | ||||
|             logger.info("Just fetched weather. ({}th time)".format(self.calls)) | ||||
|             # today = datetime.datetime.today().weekday() | ||||
|             # days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] | ||||
|  | ||||
|             try: | ||||
|                 weather = requests.get(self.url,params=data).json() | ||||
|                 # categories = {"Clouds": ":cloud:", "Rain": ":cloud_with_rain:", "Thunderstorm": "thunder_cloud_rain", "Drizzle": ":droplet:", "Snow": ":cloud_snow:", "Clear": ":sun:", "Mist": "Mist", "Smoke": "Smoke", "Haze": "Haze", "Dust": "Dust", "Fog": "Fog", "Sand": "Sand", "Dust": "Dust", "Ash": "Ash", "Squall": "Squall", "Tornado": "Tornado",} | ||||
|                 now = weather["current"] | ||||
|                 ret_weather = [] | ||||
|                 ret_weather.append({ | ||||
|                     "short" : now["weather"][0]["main"], | ||||
|                     "temps" : [int(now["temp"])] | ||||
|                     }) | ||||
|                 weather_days = weather["daily"] | ||||
|                 for i, day in enumerate(weather_days): | ||||
|                     ret_weather.append({ | ||||
|                         "short" : day["weather"][0]["main"], | ||||
|                         "temps" : [int(day["temp"]["min"]),int(day["temp"]["max"])] | ||||
|                         }) | ||||
|             except: | ||||
|                 ret_weather = [] | ||||
|  | ||||
|              | ||||
|             #     now = weather["current"] | ||||
|             #     message = "<b>Now:</b> " + categories[now["weather"][0]["main"]] + "\n" | ||||
|             #     message += ":thermometer: " + str(int(now["temp"])) + "°\n\n" | ||||
|  | ||||
|             #     weather_days = weather["daily"] | ||||
|                  | ||||
|             #     for i, day in enumerate(weather_days): | ||||
|             #         if i == 0: | ||||
|             #             message += "<b>" + "Today" + ":</b> " + categories[day["weather"][0]["main"]] + "\n" | ||||
|             #         else: | ||||
|             #             message += "<b>" + days[(today + i + 1) % 7] + ":</b> " + categories[day["weather"][0]["main"]] + "\n" | ||||
|             #         message += ":thermometer: :fast_down_button: " + str(int(day["temp"]["min"])) + "° , :thermometer: :fast_up_button: " + str(int(day["temp"]["max"])) + "°\n\n" | ||||
|             # except: | ||||
|             #     message = "Query failed, it's my fault, I'm sorry :sad:" | ||||
|              | ||||
|             self.last_weather = ret_weather | ||||
|             self.last_fetch = datetime.datetime.now() | ||||
|         else: | ||||
|             ret_weather = self.last_weather | ||||
|  | ||||
|         return ret_weather | ||||
|  | ||||
|     # def get_weather_by_city(self, city): | ||||
|     #     loc = get_coords_from_city(self, city) | ||||
|     #     weather = self.show_weather(loc) | ||||
|     #     return weather | ||||
|          | ||||
|          | ||||
|     # def get_coords_from_city(self, city): | ||||
|     #     url = "https://devru-latitude-longitude-find-v1.p.rapidapi.com/latlon.php" | ||||
|     #     data = {"location": city} | ||||
|     #     headers = { | ||||
|     #         "x-rapidapi-key" : "d4e0ab7ab3mshd5dde5a282649e0p11fd98jsnc93afd98e3aa", | ||||
|     #         "x-rapidapi-host" : "devru-latitude-longitude-find-v1.p.rapidapi.com", | ||||
|     #     } | ||||
|  | ||||
|     #     #try: | ||||
|     #     resp = requests.request("GET", url, headers=headers, params=data) | ||||
|     #     result = resp.text | ||||
|     #     #except: | ||||
|     #     #    result = "???" | ||||
|     #     return result | ||||
|  | ||||
| import requests | ||||
| import datetime | ||||
|  | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
| class WeatherFetch(): | ||||
|     def __init__(self, key): | ||||
|         self.last_fetch = datetime.datetime.fromtimestamp(0) | ||||
|         self.last_weather = "" | ||||
|         self.calls = 0 | ||||
|  | ||||
|         self.url = "https://api.openweathermap.org/data/2.5/onecall?" | ||||
|         self.key = key | ||||
|  | ||||
|     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: | ||||
|  | ||||
|              | ||||
|             data = {"lat" : location[0], "lon" : location[1], "exclude" : "minutely,hourly", "appid" : self.key, "units" : "metric"} | ||||
|             self.calls += 1 | ||||
|             logger.info("Just fetched weather. ({}th time)".format(self.calls)) | ||||
|             # today = datetime.datetime.today().weekday() | ||||
|             # days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] | ||||
|  | ||||
|             try: | ||||
|                 weather = requests.get(self.url,params=data).json() | ||||
|                 # categories = {"Clouds": ":cloud:", "Rain": ":cloud_with_rain:", "Thunderstorm": "thunder_cloud_rain", "Drizzle": ":droplet:", "Snow": ":cloud_snow:", "Clear": ":sun:", "Mist": "Mist", "Smoke": "Smoke", "Haze": "Haze", "Dust": "Dust", "Fog": "Fog", "Sand": "Sand", "Dust": "Dust", "Ash": "Ash", "Squall": "Squall", "Tornado": "Tornado",} | ||||
|                 now = weather["current"] | ||||
|                 ret_weather = [] | ||||
|                 ret_weather.append({ | ||||
|                     "short" : now["weather"][0]["main"], | ||||
|                     "temps" : [int(now["temp"])] | ||||
|                     }) | ||||
|                 weather_days = weather["daily"] | ||||
|                 for i, day in enumerate(weather_days): | ||||
|                     ret_weather.append({ | ||||
|                         "short" : day["weather"][0]["main"], | ||||
|                         "temps" : [int(day["temp"]["min"]),int(day["temp"]["max"])] | ||||
|                         }) | ||||
|             except: | ||||
|                 ret_weather = [] | ||||
|  | ||||
|              | ||||
|             #     now = weather["current"] | ||||
|             #     message = "<b>Now:</b> " + categories[now["weather"][0]["main"]] + "\n" | ||||
|             #     message += ":thermometer: " + str(int(now["temp"])) + "°\n\n" | ||||
|  | ||||
|             #     weather_days = weather["daily"] | ||||
|                  | ||||
|             #     for i, day in enumerate(weather_days): | ||||
|             #         if i == 0: | ||||
|             #             message += "<b>" + "Today" + ":</b> " + categories[day["weather"][0]["main"]] + "\n" | ||||
|             #         else: | ||||
|             #             message += "<b>" + days[(today + i + 1) % 7] + ":</b> " + categories[day["weather"][0]["main"]] + "\n" | ||||
|             #         message += ":thermometer: :fast_down_button: " + str(int(day["temp"]["min"])) + "° , :thermometer: :fast_up_button: " + str(int(day["temp"]["max"])) + "°\n\n" | ||||
|             # except: | ||||
|             #     message = "Query failed, it's my fault, I'm sorry :sad:" | ||||
|              | ||||
|             self.last_weather = ret_weather | ||||
|             self.last_fetch = datetime.datetime.now() | ||||
|         else: | ||||
|             ret_weather = self.last_weather | ||||
|  | ||||
|         return ret_weather | ||||
|  | ||||
|     # def get_weather_by_city(self, city): | ||||
|     #     loc = get_coords_from_city(self, city) | ||||
|     #     weather = self.show_weather(loc) | ||||
|     #     return weather | ||||
|          | ||||
|          | ||||
|     # def get_coords_from_city(self, city): | ||||
|     #     url = "https://devru-latitude-longitude-find-v1.p.rapidapi.com/latlon.php" | ||||
|     #     data = {"location": city} | ||||
|     #     headers = { | ||||
|     #         "x-rapidapi-key" : "d4e0ab7ab3mshd5dde5a282649e0p11fd98jsnc93afd98e3aa", | ||||
|     #         "x-rapidapi-host" : "devru-latitude-longitude-find-v1.p.rapidapi.com", | ||||
|     #     } | ||||
|  | ||||
|     #     #try: | ||||
|     #     resp = requests.request("GET", url, headers=headers, params=data) | ||||
|     #     result = resp.text | ||||
|     #     #except: | ||||
|     #     #    result = "???" | ||||
|     #     return result | ||||
|  | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # Placeholder | ||||
| from . import clock, help, weather, status, zvv, lists, alias, plaintext, reddit, search | ||||
| # Placeholder | ||||
| from . import clock, help, weather, status, zvv, lists, alias, plaintext, reddit, search | ||||
|   | ||||
| @@ -1,64 +1,64 @@ | ||||
| from .template import * | ||||
|  | ||||
| FIRST = range(1) | ||||
| class Alias(BotFunc): | ||||
|     """create a new command for command-paths you often use""" | ||||
|  | ||||
|     def __init__(self, dispatcher, db): | ||||
|         super().__init__(db) | ||||
|         self.dispatcher = dispatcher | ||||
|         # do not interact with him yet! | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('alias', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.print_all, pattern="^all$"), | ||||
|                     CallbackQueryHandler(self.create_alias, pattern="^new$"), | ||||
|                     CallbackQueryHandler(self.delete_alias, pattern='^delete$'), | ||||
|                 ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('alias', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         test = self.dispatcher | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("All aliases", callback_data="all")], | ||||
|             [InlineKeyboardButton("Create new alias", callback_data="new")], | ||||
|             [InlineKeyboardButton("Delete alias", callback_data="delete")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(receive=True, execute=False, send=True) | ||||
|         update.message.reply_text("What exactly do you want?", reply_markup=reply_markup) | ||||
|         return FIRST | ||||
|      | ||||
|  | ||||
|     def print_all(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         all_alias = "" | ||||
|         for k in self.persistence["bot"]["aliases"]: | ||||
|             all_alias += k + " - " + self.persistence["bot"]["aliases"] +"\n" | ||||
|  | ||||
|         query.edit_message_text(text="List of all commands:\n" + all_alias) | ||||
|         return ConversationHandler.END | ||||
|      | ||||
|      | ||||
|     def create_alias(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         all_alias = "" | ||||
|         for k in self.persistence["bot"]["aliases"]: | ||||
|             all_alias += k + " - " + self.persistence["bot"]["aliases"] +"\n" | ||||
|  | ||||
|         query.edit_message_text(text="List of all commands:\n" + all_alias) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|     def delete_alias(self, update: Update, context: CallbackContext) -> None: | ||||
| from .template import * | ||||
|  | ||||
| FIRST = range(1) | ||||
| class Alias(BotFunc): | ||||
|     """create a new command for command-paths you often use""" | ||||
|  | ||||
|     def __init__(self, dispatcher, db): | ||||
|         super().__init__(db) | ||||
|         self.dispatcher = dispatcher | ||||
|         # do not interact with him yet! | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('alias', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.print_all, pattern="^all$"), | ||||
|                     CallbackQueryHandler(self.create_alias, pattern="^new$"), | ||||
|                     CallbackQueryHandler(self.delete_alias, pattern='^delete$'), | ||||
|                 ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('alias', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         test = self.dispatcher | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("All aliases", callback_data="all")], | ||||
|             [InlineKeyboardButton("Create new alias", callback_data="new")], | ||||
|             [InlineKeyboardButton("Delete alias", callback_data="delete")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(receive=True, execute=False, send=True) | ||||
|         update.message.reply_text("What exactly do you want?", reply_markup=reply_markup) | ||||
|         return FIRST | ||||
|      | ||||
|  | ||||
|     def print_all(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         all_alias = "" | ||||
|         for k in self.persistence["bot"]["aliases"]: | ||||
|             all_alias += k + " - " + self.persistence["bot"]["aliases"] +"\n" | ||||
|  | ||||
|         query.edit_message_text(text="List of all commands:\n" + all_alias) | ||||
|         return ConversationHandler.END | ||||
|      | ||||
|      | ||||
|     def create_alias(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         all_alias = "" | ||||
|         for k in self.persistence["bot"]["aliases"]: | ||||
|             all_alias += k + " - " + self.persistence["bot"]["aliases"] +"\n" | ||||
|  | ||||
|         query.edit_message_text(text="List of all commands:\n" + all_alias) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|     def delete_alias(self, update: Update, context: CallbackContext) -> None: | ||||
|         return ConversationHandler.END | ||||
| @@ -1,218 +1,218 @@ | ||||
| from .template import * | ||||
| import time | ||||
| import numpy | ||||
| from PIL import Image | ||||
| import io | ||||
|  | ||||
| CHOOSE, ADDARG = range(2) | ||||
| MESSAGE, WAKE, ALARM, IMAGE, ART = range(3,8) | ||||
|  | ||||
| class Clock(BotFunc): | ||||
|     """pass on commands to clock-module""" | ||||
|     def __init__(self, prst, clock_module, art_api): | ||||
|         super().__init__(prst) | ||||
|         self.clock = clock_module | ||||
|         self.api_art = art_api | ||||
|  | ||||
|     def create_handler(self): | ||||
|         handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler("clock", self.entry_point)], | ||||
|             states={ | ||||
|                 CHOOSE : [ | ||||
|                     CallbackQueryHandler(self.wake_light, pattern="^wake$"), | ||||
|                     CallbackQueryHandler(self.alarm_blink, pattern="^alarm$"), | ||||
|                     CallbackQueryHandler(self.show_message, pattern="^message$"), | ||||
|                     CallbackQueryHandler(self.show_image, pattern="^image$"), | ||||
|                     CallbackQueryHandler(self.art_gallery, pattern="^gallery$"), | ||||
|                 ], | ||||
|                 ADDARG : [MessageHandler(Filters.text, callback=self.get_arg1)], | ||||
|                 MESSAGE: [MessageHandler(Filters.text, callback=self.exec_show_message)], | ||||
|                 WAKE : [MessageHandler(Filters.text, callback=self.exec_wake_light)], | ||||
|                 ALARM : [MessageHandler(Filters.text, callback=self.exec_alarm_blink)], | ||||
|                 IMAGE : [MessageHandler(Filters.photo, callback=self.exec_show_image)], | ||||
|                 ART : [MessageHandler(Filters.text, callback=self.exec_art_gallery)], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('clock', self.entry_point)], | ||||
|         ) | ||||
|         return handler | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("Make a wake-light", callback_data="wake")], | ||||
|             [InlineKeyboardButton("Blink as alarm", callback_data="alarm")], | ||||
|             [InlineKeyboardButton("Show a message", callback_data="message")], | ||||
|             [InlineKeyboardButton("Show an image", callback_data="image")], | ||||
|             [InlineKeyboardButton("Art gallery!", callback_data="gallery")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         update.message.reply_text("What exactly do you want?", reply_markup=reply_markup) | ||||
|         return CHOOSE | ||||
|  | ||||
|  | ||||
|     def wake_light(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. How long should the color cycle last? (In seconds)") | ||||
|         return WAKE | ||||
|  | ||||
|     def alarm_blink(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. How long should it blink? (In seconds)") | ||||
|         self.next_state = {ALARM : "What frequency (Hertz)"} | ||||
|         return ADDARG | ||||
|  | ||||
|     def show_message(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. What message will I show?") | ||||
|         return MESSAGE | ||||
|  | ||||
|     def show_image(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("How long (in minutes) should the image be displayed?") | ||||
|         self.next_state = {IMAGE : "Please send me the photo to display."} | ||||
|         return ADDARG | ||||
|  | ||||
|     def art_gallery(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. How long should we display art? (in hours") | ||||
|         self.next_state = {ART : "And how many artworks would you like to see during that time?"} | ||||
|         return ADDARG | ||||
|  | ||||
|     def get_arg1(self, update: Update, context: CallbackContext) -> None: | ||||
|         a = update.message.text | ||||
|         self.additional_argument = a | ||||
|         update.message.reply_text("Furthermore: "+ list(self.next_state.values())[0]) | ||||
|         return list(self.next_state.keys())[0] | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
| ###### actually running clock actions | ||||
|     def exec_wake_light(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = update.message.text | ||||
|  | ||||
|         def output(duration): | ||||
|             self.clock.set_brightness(value=1) | ||||
|             start_color = numpy.array([153, 0, 51]) | ||||
|             end_color = numpy.array([255, 255, 0]) | ||||
|             col_show = numpy.zeros((*self.clock.shape, 3)) | ||||
|             col_show[:,:,...] = start_color | ||||
|  | ||||
|             gradient = end_color - start_color | ||||
|             # 20 steps should be fine => sleep_time = duration / 20 | ||||
|             for i in range(20): | ||||
|                 ct = i/20 * gradient | ||||
|                 col_show[:,:,...] = [int(x) for x in ct+start_color] | ||||
|                 self.clock.IO.put(col_show) | ||||
|                 time.sleep(int(duration) / 20) | ||||
|  | ||||
|         self.clock.run(output,(duration,)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def exec_alarm_blink(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = self.additional_argument | ||||
|         frequency = update.message.text | ||||
|  | ||||
|         def output(duration, frequency): | ||||
|             self.clock.set_brightness(value=1) | ||||
|             duration =  int(duration) | ||||
|             frequency = int(frequency) | ||||
|             n = duration * frequency / 2 | ||||
|             empty = numpy.zeros((*self.clock.shape,3)) | ||||
|             red = empty.copy() | ||||
|             red[...,0] = 255 | ||||
|             for i in range(int(n)): | ||||
|                 self.clock.IO.put(red) | ||||
|                 time.sleep(1/frequency) | ||||
|                 self.clock.IO.put(empty) | ||||
|                 time.sleep(1/frequency) | ||||
|  | ||||
|         if not(duration == 0 or frequency == 0): | ||||
|             update.message.reply_text("Now blinking") | ||||
|             self.clock.run(output,(duration, frequency)) | ||||
|         return ConversationHandler.END | ||||
|          | ||||
|  | ||||
|  | ||||
|     def exec_show_image(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = self.additional_argument | ||||
|         i = update.message.photo | ||||
|         img = update.message.photo[0] | ||||
|         bot = img.bot | ||||
|         id = img.file_id | ||||
|  | ||||
|         file = bot.getFile(id).download_as_bytearray() | ||||
|         width = self.clock.shape[1] | ||||
|         height = self.clock.shape[0] | ||||
|  | ||||
|         img = Image.open(io.BytesIO(file)) | ||||
|         im_height = img.height | ||||
|         im_width = img.width | ||||
|  | ||||
|         scalex = im_width // width | ||||
|         scaley = im_height // height | ||||
|         scale = min(scalex, scaley) | ||||
|  | ||||
|         t = img.resize((width, height),box=(0,0,width*scale,height*scale)) | ||||
|         a = numpy.asarray(t) | ||||
|          | ||||
|         def output(image, duration): | ||||
|             self.clock.IO.put(image) | ||||
|             time.sleep(int(duration) * 60) | ||||
|  | ||||
|         self.clock.run(output,(a, duration)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def exec_show_message(self, update: Update, context: CallbackContext) -> None: | ||||
|         message_str = update.message.text | ||||
|         update.message.reply_text("Now showing: " + message_str) | ||||
|         self.clock.run(self.clock.text_scroll,(message_str,)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def exec_art_gallery(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = float(self.additional_argument) | ||||
|         number = int(update.message.text) | ||||
|          | ||||
|         def output(number, duration): | ||||
|             for i in range(number): | ||||
|                 img = self.api_art.get_random_art() # returns an PIL.Image object | ||||
|                 im_height = img.height | ||||
|                 im_width = img.width | ||||
|  | ||||
|                 width = self.clock.shape[1] | ||||
|                 height = self.clock.shape[0] | ||||
|                  | ||||
|                 scalex = im_width // width | ||||
|                 scaley = im_height // height | ||||
|                 scale = min(scalex, scaley) | ||||
|  | ||||
|                 t = img.resize((width, height),box=(0,0,width*scale,height*scale)) | ||||
|                 a = numpy.asarray(t) | ||||
|                 self.clock.IO.put(a) | ||||
|  | ||||
|                 time.sleep(duration*3600 / number) | ||||
|  | ||||
|  | ||||
|         update.message.reply_text("Ok. Showing art for the next "+ str(duration) + " hours.") | ||||
|         self.clock.run(output,(number, duration)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| from .template import * | ||||
| import time | ||||
| import numpy | ||||
| from PIL import Image | ||||
| import io | ||||
|  | ||||
| CHOOSE, ADDARG = range(2) | ||||
| MESSAGE, WAKE, ALARM, IMAGE, ART = range(3,8) | ||||
|  | ||||
| class Clock(BotFunc): | ||||
|     """pass on commands to clock-module""" | ||||
|     def __init__(self, prst, clock_module, art_api): | ||||
|         super().__init__(prst) | ||||
|         self.clock = clock_module | ||||
|         self.api_art = art_api | ||||
|  | ||||
|     def create_handler(self): | ||||
|         handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler("clock", self.entry_point)], | ||||
|             states={ | ||||
|                 CHOOSE : [ | ||||
|                     CallbackQueryHandler(self.wake_light, pattern="^wake$"), | ||||
|                     CallbackQueryHandler(self.alarm_blink, pattern="^alarm$"), | ||||
|                     CallbackQueryHandler(self.show_message, pattern="^message$"), | ||||
|                     CallbackQueryHandler(self.show_image, pattern="^image$"), | ||||
|                     CallbackQueryHandler(self.art_gallery, pattern="^gallery$"), | ||||
|                 ], | ||||
|                 ADDARG : [MessageHandler(Filters.text, callback=self.get_arg1)], | ||||
|                 MESSAGE: [MessageHandler(Filters.text, callback=self.exec_show_message)], | ||||
|                 WAKE : [MessageHandler(Filters.text, callback=self.exec_wake_light)], | ||||
|                 ALARM : [MessageHandler(Filters.text, callback=self.exec_alarm_blink)], | ||||
|                 IMAGE : [MessageHandler(Filters.photo, callback=self.exec_show_image)], | ||||
|                 ART : [MessageHandler(Filters.text, callback=self.exec_art_gallery)], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('clock', self.entry_point)], | ||||
|         ) | ||||
|         return handler | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("Make a wake-light", callback_data="wake")], | ||||
|             [InlineKeyboardButton("Blink as alarm", callback_data="alarm")], | ||||
|             [InlineKeyboardButton("Show a message", callback_data="message")], | ||||
|             [InlineKeyboardButton("Show an image", callback_data="image")], | ||||
|             [InlineKeyboardButton("Art gallery!", callback_data="gallery")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         update.message.reply_text("What exactly do you want?", reply_markup=reply_markup) | ||||
|         return CHOOSE | ||||
|  | ||||
|  | ||||
|     def wake_light(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. How long should the color cycle last? (In seconds)") | ||||
|         return WAKE | ||||
|  | ||||
|     def alarm_blink(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. How long should it blink? (In seconds)") | ||||
|         self.next_state = {ALARM : "What frequency (Hertz)"} | ||||
|         return ADDARG | ||||
|  | ||||
|     def show_message(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. What message will I show?") | ||||
|         return MESSAGE | ||||
|  | ||||
|     def show_image(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("How long (in minutes) should the image be displayed?") | ||||
|         self.next_state = {IMAGE : "Please send me the photo to display."} | ||||
|         return ADDARG | ||||
|  | ||||
|     def art_gallery(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         query.edit_message_text("Ok. How long should we display art? (in hours") | ||||
|         self.next_state = {ART : "And how many artworks would you like to see during that time?"} | ||||
|         return ADDARG | ||||
|  | ||||
|     def get_arg1(self, update: Update, context: CallbackContext) -> None: | ||||
|         a = update.message.text | ||||
|         self.additional_argument = a | ||||
|         update.message.reply_text("Furthermore: "+ list(self.next_state.values())[0]) | ||||
|         return list(self.next_state.keys())[0] | ||||
|      | ||||
|  | ||||
|  | ||||
|  | ||||
| ###### actually running clock actions | ||||
|     def exec_wake_light(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = update.message.text | ||||
|  | ||||
|         def output(duration): | ||||
|             self.clock.set_brightness(value=1) | ||||
|             start_color = numpy.array([153, 0, 51]) | ||||
|             end_color = numpy.array([255, 255, 0]) | ||||
|             col_show = numpy.zeros((*self.clock.shape, 3)) | ||||
|             col_show[:,:,...] = start_color | ||||
|  | ||||
|             gradient = end_color - start_color | ||||
|             # 20 steps should be fine => sleep_time = duration / 20 | ||||
|             for i in range(20): | ||||
|                 ct = i/20 * gradient | ||||
|                 col_show[:,:,...] = [int(x) for x in ct+start_color] | ||||
|                 self.clock.IO.put(col_show) | ||||
|                 time.sleep(int(duration) / 20) | ||||
|  | ||||
|         self.clock.run(output,(duration,)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def exec_alarm_blink(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = self.additional_argument | ||||
|         frequency = update.message.text | ||||
|  | ||||
|         def output(duration, frequency): | ||||
|             self.clock.set_brightness(value=1) | ||||
|             duration =  int(duration) | ||||
|             frequency = int(frequency) | ||||
|             n = duration * frequency / 2 | ||||
|             empty = numpy.zeros((*self.clock.shape,3)) | ||||
|             red = empty.copy() | ||||
|             red[...,0] = 255 | ||||
|             for i in range(int(n)): | ||||
|                 self.clock.IO.put(red) | ||||
|                 time.sleep(1/frequency) | ||||
|                 self.clock.IO.put(empty) | ||||
|                 time.sleep(1/frequency) | ||||
|  | ||||
|         if not(duration == 0 or frequency == 0): | ||||
|             update.message.reply_text("Now blinking") | ||||
|             self.clock.run(output,(duration, frequency)) | ||||
|         return ConversationHandler.END | ||||
|          | ||||
|  | ||||
|  | ||||
|     def exec_show_image(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = self.additional_argument | ||||
|         i = update.message.photo | ||||
|         img = update.message.photo[0] | ||||
|         bot = img.bot | ||||
|         id = img.file_id | ||||
|  | ||||
|         file = bot.getFile(id).download_as_bytearray() | ||||
|         width = self.clock.shape[1] | ||||
|         height = self.clock.shape[0] | ||||
|  | ||||
|         img = Image.open(io.BytesIO(file)) | ||||
|         im_height = img.height | ||||
|         im_width = img.width | ||||
|  | ||||
|         scalex = im_width // width | ||||
|         scaley = im_height // height | ||||
|         scale = min(scalex, scaley) | ||||
|  | ||||
|         t = img.resize((width, height),box=(0,0,width*scale,height*scale)) | ||||
|         a = numpy.asarray(t) | ||||
|          | ||||
|         def output(image, duration): | ||||
|             self.clock.IO.put(image) | ||||
|             time.sleep(int(duration) * 60) | ||||
|  | ||||
|         self.clock.run(output,(a, duration)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def exec_show_message(self, update: Update, context: CallbackContext) -> None: | ||||
|         message_str = update.message.text | ||||
|         update.message.reply_text("Now showing: " + message_str) | ||||
|         self.clock.run(self.clock.text_scroll,(message_str,)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def exec_art_gallery(self, update: Update, context: CallbackContext) -> None: | ||||
|         duration = float(self.additional_argument) | ||||
|         number = int(update.message.text) | ||||
|          | ||||
|         def output(number, duration): | ||||
|             for i in range(number): | ||||
|                 img = self.api_art.get_random_art() # returns an PIL.Image object | ||||
|                 im_height = img.height | ||||
|                 im_width = img.width | ||||
|  | ||||
|                 width = self.clock.shape[1] | ||||
|                 height = self.clock.shape[0] | ||||
|                  | ||||
|                 scalex = im_width // width | ||||
|                 scaley = im_height // height | ||||
|                 scale = min(scalex, scaley) | ||||
|  | ||||
|                 t = img.resize((width, height),box=(0,0,width*scale,height*scale)) | ||||
|                 a = numpy.asarray(t) | ||||
|                 self.clock.IO.put(a) | ||||
|  | ||||
|                 time.sleep(duration*3600 / number) | ||||
|  | ||||
|  | ||||
|         update.message.reply_text("Ok. Showing art for the next "+ str(duration) + " hours.") | ||||
|         self.clock.run(output,(number, duration)) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| # TODO FIx this to work with the new backend | ||||
| @@ -1,128 +1,128 @@ | ||||
| from .template import * | ||||
|  | ||||
| FIRST, EXECUTE = range(2) | ||||
|  | ||||
|  | ||||
| class Help(BotFunc): | ||||
|     """Shows the functions and their usage""" | ||||
|      | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('help', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.print_all, pattern="^all$"), | ||||
|                     CallbackQueryHandler(self.choose_specific, pattern="^specific$"), | ||||
|                     CallbackQueryHandler(self.print_one, pattern='func-'), | ||||
|                 ], | ||||
|                 EXECUTE :[CallbackQueryHandler(self.execute_now)], | ||||
|                 # ConversationHandler.TIMEOUT : [ | ||||
|                 #     CallbackQueryHandler(self.timeout) | ||||
|                 # ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('help', self.entry_point)], | ||||
|             conversation_timeout=15, | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|     def add_commands(self, commands): | ||||
|         # commands is a dict {"name": class} | ||||
|         for k in commands: | ||||
|             if k != "plaintext": | ||||
|                 self.available_commands[k] = commands[k].__doc__ | ||||
|  | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|  | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("All commands", callback_data="all"), | ||||
|                 InlineKeyboardButton("Just one", callback_data="specific"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=True, send=True) # at this point every step has been fulfilled | ||||
|         if update.message: | ||||
|             update.message.reply_text("What exactly do you want?", reply_markup=reply_markup) | ||||
|         else: | ||||
|             update._effective_chat.send_message("What exactly do you want?", reply_markup=reply_markup) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def print_all(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         all_cmd = "" | ||||
|         for h in self.available_commands: | ||||
|             all_cmd += "{} - `{}`\n".format(h, self.available_commands[h]) | ||||
|  | ||||
|         query.edit_message_text(text="List of all commands:\n" + all_cmd, parse_mode = ParseMode.MARKDOWN) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def choose_specific(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|          | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data="func-" + k)] for k in self.available_commands] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text( | ||||
|             text="What command should be printed?", reply_markup=reply_markup | ||||
|         ) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def print_one(self, update: Update, context: CallbackContext) -> None: | ||||
|         """Show new choice of buttons""" | ||||
|         query = update.callback_query | ||||
|         name = query.data.replace("func-", "") | ||||
|         query.answer() | ||||
|  | ||||
|         message = name + ": `" + self.available_commands[name] + "`" | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton("Call " + name + " now", callback_data=name),]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text( | ||||
|             text= message, | ||||
|             reply_markup = reply_markup, | ||||
|             parse_mode = ParseMode.MARKDOWN_V2 | ||||
|         ) | ||||
|         return EXECUTE | ||||
|  | ||||
|  | ||||
|     def execute_now(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         name = query.data | ||||
|         query.answer() | ||||
|         funcs = context.dispatcher.handlers[0] | ||||
|         for func in funcs: | ||||
|             if name == func.entry_points[0].command[0]: | ||||
|                 break | ||||
|         callback = func.entry_points[0].handle_update | ||||
|         callback(update, context.dispatcher, check_result=True, context=context) | ||||
|         return ConversationHandler.END | ||||
|          | ||||
|  | ||||
|     def timeout(self, update: Update, context: CallbackContext) -> None: | ||||
|         """For dying conversation. Currently unused.""" | ||||
|  | ||||
|         query = update.callback_query | ||||
|         name = query.data.replace("func-", "") | ||||
|         query.answer() | ||||
|  | ||||
|         message = name + ": `" + self.available_commands[name] + "`" | ||||
|         query.edit_message_text( | ||||
|             text= "Timed out...", | ||||
|             parse_mode = ParseMode.MARKDOWN_V2 | ||||
|         ) | ||||
| from .template import * | ||||
|  | ||||
| FIRST, EXECUTE = range(2) | ||||
|  | ||||
|  | ||||
| class Help(BotFunc): | ||||
|     """Shows the functions and their usage""" | ||||
|      | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('help', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.print_all, pattern="^all$"), | ||||
|                     CallbackQueryHandler(self.choose_specific, pattern="^specific$"), | ||||
|                     CallbackQueryHandler(self.print_one, pattern='func-'), | ||||
|                 ], | ||||
|                 EXECUTE :[CallbackQueryHandler(self.execute_now)], | ||||
|                 # ConversationHandler.TIMEOUT : [ | ||||
|                 #     CallbackQueryHandler(self.timeout) | ||||
|                 # ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('help', self.entry_point)], | ||||
|             conversation_timeout=15, | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|     def add_commands(self, commands): | ||||
|         # commands is a dict {"name": class} | ||||
|         for k in commands: | ||||
|             if k != "plaintext": | ||||
|                 self.available_commands[k] = commands[k].__doc__ | ||||
|  | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|  | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("All commands", callback_data="all"), | ||||
|                 InlineKeyboardButton("Just one", callback_data="specific"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=True, send=True) # at this point every step has been fulfilled | ||||
|         if update.message: | ||||
|             update.message.reply_text("What exactly do you want?", reply_markup=reply_markup) | ||||
|         else: | ||||
|             update._effective_chat.send_message("What exactly do you want?", reply_markup=reply_markup) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def print_all(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         all_cmd = "" | ||||
|         for h in self.available_commands: | ||||
|             all_cmd += "{} - `{}`\n".format(h, self.available_commands[h]) | ||||
|  | ||||
|         query.edit_message_text(text="List of all commands:\n" + all_cmd, parse_mode = ParseMode.MARKDOWN) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def choose_specific(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|          | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data="func-" + k)] for k in self.available_commands] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text( | ||||
|             text="What command should be printed?", reply_markup=reply_markup | ||||
|         ) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def print_one(self, update: Update, context: CallbackContext) -> None: | ||||
|         """Show new choice of buttons""" | ||||
|         query = update.callback_query | ||||
|         name = query.data.replace("func-", "") | ||||
|         query.answer() | ||||
|  | ||||
|         message = name + ": `" + self.available_commands[name] + "`" | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton("Call " + name + " now", callback_data=name),]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text( | ||||
|             text= message, | ||||
|             reply_markup = reply_markup, | ||||
|             parse_mode = ParseMode.MARKDOWN_V2 | ||||
|         ) | ||||
|         return EXECUTE | ||||
|  | ||||
|  | ||||
|     def execute_now(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         name = query.data | ||||
|         query.answer() | ||||
|         funcs = context.dispatcher.handlers[0] | ||||
|         for func in funcs: | ||||
|             if name == func.entry_points[0].command[0]: | ||||
|                 break | ||||
|         callback = func.entry_points[0].handle_update | ||||
|         callback(update, context.dispatcher, check_result=True, context=context) | ||||
|         return ConversationHandler.END | ||||
|          | ||||
|  | ||||
|     def timeout(self, update: Update, context: CallbackContext) -> None: | ||||
|         """For dying conversation. Currently unused.""" | ||||
|  | ||||
|         query = update.callback_query | ||||
|         name = query.data.replace("func-", "") | ||||
|         query.answer() | ||||
|  | ||||
|         message = name + ": `" + self.available_commands[name] + "`" | ||||
|         query.edit_message_text( | ||||
|             text= "Timed out...", | ||||
|             parse_mode = ParseMode.MARKDOWN_V2 | ||||
|         ) | ||||
|         return ConversationHandler.END | ||||
| @@ -1,200 +1,198 @@ | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
| import requests | ||||
|  | ||||
| NAME, NEW, ACTION, ITEMADD, ITEMREMOVE = range(5) | ||||
|  | ||||
|  | ||||
| class Lists(BotFunc): | ||||
|     """Create and edit lists""" | ||||
|  | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|         self.current_name = "" | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('list', self.entry_point)], | ||||
|             states={ | ||||
|                 NAME: [ | ||||
|                     CallbackQueryHandler(self.choose_list, pattern="^list-"), | ||||
|                     CallbackQueryHandler(self.new_list, pattern="^new$"), | ||||
|                     ], | ||||
|                 NEW : [MessageHandler(Filters.text, callback=self.new_listname)], | ||||
|                 ACTION: [ | ||||
|                     CallbackQueryHandler(self.list_add, pattern="^add$"), | ||||
|                     CallbackQueryHandler(self.list_remove, pattern="^remove$"), | ||||
|                     CallbackQueryHandler(self.list_clear, pattern="^clear$"), | ||||
|                     CallbackQueryHandler(self.list_delete, pattern="^delete$"), | ||||
|                     CallbackQueryHandler(self.list_print, pattern="^print$"), | ||||
|                     CallbackQueryHandler(self.list_menu, pattern="^overview$"), | ||||
|                     ], | ||||
|                 ITEMADD : [MessageHandler(Filters.text, callback=self.list_add_item)], | ||||
|                 ITEMREMOVE : [CallbackQueryHandler(self.list_remove_index)] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('list', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         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")]] | ||||
|  | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=False, send=True) | ||||
|         update.message.reply_text(text="Here are the existing lists. You can also create a new one:", reply_markup=reply_markup) | ||||
|         return NAME | ||||
|  | ||||
|  | ||||
|     def choose_list(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         data = query.data | ||||
|         name = data.replace("list-","") | ||||
|         query.answer() | ||||
|         self.current_name = name | ||||
|  | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("Add item", callback_data="add")], | ||||
|             [InlineKeyboardButton("Remove item", callback_data="remove")], | ||||
|             [InlineKeyboardButton("Clear list", callback_data="clear")], | ||||
|             [InlineKeyboardButton("Print list", callback_data="print")], | ||||
|             [InlineKeyboardButton("Delete list", callback_data="delete")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text("Very well. For " + name + " the following actions are available:", reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     def list_menu(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("Add item", callback_data="add")], | ||||
|             [InlineKeyboardButton("Remove item", callback_data="remove")], | ||||
|             [InlineKeyboardButton("Clear list", callback_data="clear")], | ||||
|             [InlineKeyboardButton("Print list", callback_data="print")], | ||||
|             [InlineKeyboardButton("Delete list", callback_data="delete")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text("Very well. For " + self.current_name + " the following actions are available:", reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     def new_list(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         query.edit_message_text("What's the name of the new list?") | ||||
|         return NEW | ||||
|          | ||||
|  | ||||
|     def new_listname(self, update: Update, context: CallbackContext) -> None: | ||||
|         name = update.message.text | ||||
|         try: | ||||
|             data = self.db.lists(name=name, content="") | ||||
|             data.save() | ||||
|             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) | ||||
|             return ACTION | ||||
|         except Exception as e: | ||||
|             update.message.reply_text("Oh no! Encountered exception: {}".format(e)) | ||||
|             return ConversationHandler.END | ||||
|  | ||||
|      | ||||
|     def list_add(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         query.edit_message_text("What would you like to add?") | ||||
|         return ITEMADD | ||||
|  | ||||
|  | ||||
|     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("<-->") | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data=i)] for i,k in enumerate(sl)] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text("Which item would you like to remove?", reply_markup = reply_markup) | ||||
|         return ITEMREMOVE | ||||
|  | ||||
|  | ||||
|     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() | ||||
|         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) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     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() | ||||
|         query.edit_message_text("List " + self.current_name + " deleted") | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     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) | ||||
|         if it: | ||||
|             content = it.content.split("<-->") | ||||
|             content = "\n".join(content) | ||||
|         else: | ||||
|             content = "List empty" | ||||
|          | ||||
|         keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text("Content of " + self.current_name + ":\n" + content, reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     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() | ||||
|  | ||||
|         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) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     def list_remove_index(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         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 | ||||
|  | ||||
|         name = old.pop(ind) | ||||
|         new = "<-->".join(old) | ||||
|         self.db.lists.update(content=new).where(self.db.lists.name == self.current_name).execute() | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton("Remove another", callback_data="remove"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard)       | ||||
|  | ||||
|         query.edit_message_text("Removed " + name, reply_markup=reply_markup) | ||||
|         return ACTION | ||||
| from .template import * | ||||
|  | ||||
| NAME, NEW, ACTION, ITEMADD, ITEMREMOVE = range(5) | ||||
|  | ||||
|  | ||||
| class Lists(BotFunc): | ||||
|     """Create and edit lists""" | ||||
|  | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|         self.current_name = "" | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('list', self.entry_point)], | ||||
|             states={ | ||||
|                 NAME: [ | ||||
|                     CallbackQueryHandler(self.choose_list, pattern="^list-"), | ||||
|                     CallbackQueryHandler(self.new_list, pattern="^new$"), | ||||
|                     ], | ||||
|                 NEW : [MessageHandler(Filters.text, callback=self.new_listname)], | ||||
|                 ACTION: [ | ||||
|                     CallbackQueryHandler(self.list_add, pattern="^add$"), | ||||
|                     CallbackQueryHandler(self.list_remove, pattern="^remove$"), | ||||
|                     CallbackQueryHandler(self.list_clear, pattern="^clear$"), | ||||
|                     CallbackQueryHandler(self.list_delete, pattern="^delete$"), | ||||
|                     CallbackQueryHandler(self.list_print, pattern="^print$"), | ||||
|                     CallbackQueryHandler(self.list_menu, pattern="^overview$"), | ||||
|                     ], | ||||
|                 ITEMADD : [MessageHandler(Filters.text, callback=self.list_add_item)], | ||||
|                 ITEMREMOVE : [CallbackQueryHandler(self.list_remove_index)] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('list', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     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")]] | ||||
|  | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=False, send=True) | ||||
|         update.message.reply_text(text="Here are the existing lists. You can also create a new one:", reply_markup=reply_markup) | ||||
|         return NAME | ||||
|  | ||||
|  | ||||
|     def choose_list(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         data = query.data | ||||
|         name = data.replace("list-","") | ||||
|         query.answer() | ||||
|         self.current_name = name | ||||
|  | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("Add item", callback_data="add")], | ||||
|             [InlineKeyboardButton("Remove item", callback_data="remove")], | ||||
|             [InlineKeyboardButton("Clear list", callback_data="clear")], | ||||
|             [InlineKeyboardButton("Print list", callback_data="print")], | ||||
|             [InlineKeyboardButton("Delete list", callback_data="delete")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text("Very well. For " + name + " the following actions are available:", reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     def list_menu(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("Add item", callback_data="add")], | ||||
|             [InlineKeyboardButton("Remove item", callback_data="remove")], | ||||
|             [InlineKeyboardButton("Clear list", callback_data="clear")], | ||||
|             [InlineKeyboardButton("Print list", callback_data="print")], | ||||
|             [InlineKeyboardButton("Delete list", callback_data="delete")], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text("Very well. For " + self.current_name + " the following actions are available:", reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     def new_list(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         query.edit_message_text("What's the name of the new list?") | ||||
|         return NEW | ||||
|          | ||||
|  | ||||
|     def new_listname(self, update: Update, context: CallbackContext) -> None: | ||||
|         name = update.message.text | ||||
|         try: | ||||
|             data = self.db.lists(name=name, content="") | ||||
|             data.save() | ||||
|             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) | ||||
|             return ACTION | ||||
|         except Exception as e: | ||||
|             update.message.reply_text("Oh no! Encountered exception: {}".format(e)) | ||||
|             return ConversationHandler.END | ||||
|  | ||||
|      | ||||
|     def list_add(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         query.edit_message_text("What would you like to add?") | ||||
|         return ITEMADD | ||||
|  | ||||
|  | ||||
|     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("<-->") | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton(k, callback_data=i)] for i,k in enumerate(sl)] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         query.edit_message_text("Which item would you like to remove?", reply_markup = reply_markup) | ||||
|         return ITEMREMOVE | ||||
|  | ||||
|  | ||||
|     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() | ||||
|         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) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     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() | ||||
|         query.edit_message_text("List " + self.current_name + " deleted") | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     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) | ||||
|         if it: | ||||
|             content = it.content.split("<-->") | ||||
|             content = "\n".join(content) | ||||
|         else: | ||||
|             content = "List empty" | ||||
|          | ||||
|         keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text("Content of " + self.current_name + ":\n" + content, reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     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() | ||||
|  | ||||
|         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) | ||||
|         return ACTION | ||||
|  | ||||
|  | ||||
|     def list_remove_index(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         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 | ||||
|  | ||||
|         name = old.pop(ind) | ||||
|         new = "<-->".join(old) | ||||
|         self.db.lists.update(content=new).where(self.db.lists.name == self.current_name).execute() | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton("Remove another", callback_data="remove"), InlineKeyboardButton("Back to the menu", callback_data="overview")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard)       | ||||
|  | ||||
|         query.edit_message_text("Removed " + name, reply_markup=reply_markup) | ||||
|         return ACTION | ||||
|   | ||||
| @@ -1,19 +1,19 @@ | ||||
| from .template import * | ||||
|  | ||||
|  | ||||
| class Plain(BotFunc): | ||||
|     """Not a command: just keeps logs and usage_data""" | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|      | ||||
|     def create_handler(self): | ||||
|         h = MessageHandler(Filters.text, callback=self.add_to_log) | ||||
|         return h | ||||
|  | ||||
|     def add_to_log(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         super().log_activity( | ||||
|             read = True, | ||||
|             send = False, | ||||
|             execute = False | ||||
|         ) | ||||
| from .template import * | ||||
|  | ||||
|  | ||||
| class Plain(BotFunc): | ||||
|     """Not a command: just keeps logs and usage_data""" | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|      | ||||
|     def create_handler(self): | ||||
|         h = MessageHandler(Filters.text, callback=self.add_to_log) | ||||
|         return h | ||||
|  | ||||
|     def add_to_log(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         super().log_activity( | ||||
|             read = True, | ||||
|             send = False, | ||||
|             execute = False | ||||
|         ) | ||||
|   | ||||
| @@ -1,179 +1,179 @@ | ||||
| from re import U | ||||
| from .template import * | ||||
|  | ||||
|  | ||||
| CHOOSE_NUM = 1 | ||||
| class Joke(BotFunc): | ||||
|     """Tells a joke from reddit.""" | ||||
|      | ||||
|     def __init__(self, api, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|         self.api = api | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('joke', self.entry_point)], | ||||
|             states={ | ||||
|                 CHOOSE_NUM: [CallbackQueryHandler(self.get_jokes),], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('joke', self.entry_point)], | ||||
|             # conversation_timeout=5, | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         keyboard = [[InlineKeyboardButton(str(i), callback_data=str(i)) for i in range(1,11)]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=True, send=True) # at this point every step has been fulfilled | ||||
|         update.message.reply_text("How many jokes?", reply_markup=reply_markup) | ||||
|         return CHOOSE_NUM | ||||
|  | ||||
|  | ||||
|     def get_jokes(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         number = int(query.data) | ||||
|         query.answer() | ||||
|         jokes = self.api.get_random_rising("jokes", number, "text") | ||||
|         # formating | ||||
|         message = "" | ||||
|         for j in jokes: | ||||
|             message += "<b>" + j["title"] + "</b> \n" + j["content"] + "\n\n" | ||||
|         if message == "": | ||||
|             message += "Could not fetch jokes." | ||||
|         query.edit_message_text(text = message, parse_mode = ParseMode.HTML) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| CHOOSE_TOPIC = 0 | ||||
| class Meme(BotFunc): | ||||
|     """Gets the latest memes from reddit""" | ||||
|      | ||||
|     def __init__(self, api, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|         self.api = api | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('meme', self.entry_point)], | ||||
|             states={ | ||||
|                 CHOOSE_TOPIC: [CallbackQueryHandler(self.choose_topic)], | ||||
|                 CHOOSE_NUM :[CallbackQueryHandler(self.get_memes)], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('meme', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|  | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("General", callback_data="memes"),], | ||||
|             [InlineKeyboardButton("Dank memes", callback_data="dankmemes"),], | ||||
|             [InlineKeyboardButton("Maths", callback_data="mathmemes"),], | ||||
|             [InlineKeyboardButton("Physics", callback_data="physicsmemes"),], | ||||
|             [InlineKeyboardButton("Biology", callback_data="biologymemes"),], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=True, send=True) # at this point every step has been fulfilled | ||||
|         update.message.reply_text("What kind of memes?", reply_markup=reply_markup) | ||||
|         return CHOOSE_TOPIC | ||||
|  | ||||
|  | ||||
|     def choose_topic(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         d = query.data | ||||
|         query.answer() | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton(str(i), callback_data=d + "-" + str(i)) for i in range(1,11)]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text("How many memes?", reply_markup=reply_markup) | ||||
|         return CHOOSE_NUM | ||||
|  | ||||
|  | ||||
|     def get_memes(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         data = query.data.split("-") | ||||
|         query.answer() | ||||
|  | ||||
|         memes = self.api.get_random_rising(data[0], int(data[1]), "photo") | ||||
|         if len(memes) != 0: | ||||
|             for m in memes: | ||||
|                 super().log_activity(read=False, execute=False, send=True) # we just sent an additional message | ||||
|                 update.effective_chat.send_photo(photo = m["image"],caption = m["caption"]) | ||||
|         else: | ||||
|            update.effective_chat.send_message("Sorry, the meme won't yeet.") | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| # class News(BotFunc): | ||||
| #     """Gets the latest news from reddit""" | ||||
|      | ||||
| #     def __init__(self, api, prst): | ||||
| #         super().__init__(prst) | ||||
| #         self.available_commands = {} | ||||
| #         self.api = api | ||||
|  | ||||
|  | ||||
| #     def create_handler(self): | ||||
| #         conv_handler = ConversationHandler( | ||||
| #             entry_points=[CommandHandler('news', self.entry_point)], | ||||
| #             states={ | ||||
| #                 CHOOSE_TOPIC: [CallbackQueryHandler(self.choose_topic)], | ||||
| #                 CHOOSE_NUM :[CallbackQueryHandler(self.get_news)], | ||||
| #             }, | ||||
| #             fallbacks=[CommandHandler('news', self.entry_point)], | ||||
| #         ) | ||||
| #         return conv_handler | ||||
|  | ||||
|  | ||||
| #     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
| #         super().entry_point() | ||||
|  | ||||
| #         keyboard = [ | ||||
| #             [InlineKeyboardButton("World", callback_data="worldnews"),], | ||||
| #             [InlineKeyboardButton("Germany", callback_data="germannews"),], | ||||
| #             [InlineKeyboardButton("France", callback_data="francenews"),], | ||||
| #             [InlineKeyboardButton("Europe", callback_data="eunews"),], | ||||
| #             [InlineKeyboardButton("USA", callback_data="usanews"),], | ||||
| #         ] | ||||
| #         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
| #         update.message.reply_text("What kind of news?", reply_markup=reply_markup) | ||||
| #         return CHOOSE_TOPIC | ||||
|  | ||||
|  | ||||
| #     def choose_topic(self, update: Update, context: CallbackContext) -> None: | ||||
| #         super().entry_point() | ||||
| #         query = update.callback_query | ||||
| #         d = query.data | ||||
| #         query.answer() | ||||
|  | ||||
| #         keyboard = [[InlineKeyboardButton(str(i), callback_data=d + "-" + str(i)) for i in range(1,11)]] | ||||
| #         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
| #         query.edit_message_text("How many entries?", reply_markup=reply_markup) | ||||
| #         return CHOOSE_NUM | ||||
|  | ||||
|  | ||||
| #     def get_news(self, update: Update, context: CallbackContext) -> None: | ||||
| #         query = update.callback_query | ||||
| #         data = query.data.split("-") | ||||
| #         query.answer() | ||||
| #         #try: | ||||
| #         news = self.api.get_top(data[0], data[1], "text") | ||||
| #         # formating | ||||
| #         message = "" | ||||
| #         for j in news: | ||||
| #             message += "<b>" + j["title"] + "</b> \n" + j["content"] + "\n\n" | ||||
| #         if message == "": | ||||
| #             message += "Could not fetch news." | ||||
| #         query.edit_message_text(news, paresemode=ParseMode.HTML) | ||||
| from re import U | ||||
| from .template import * | ||||
|  | ||||
|  | ||||
| CHOOSE_NUM = 1 | ||||
| class Joke(BotFunc): | ||||
|     """Tells a joke from reddit.""" | ||||
|      | ||||
|     def __init__(self, api, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|         self.api = api | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('joke', self.entry_point)], | ||||
|             states={ | ||||
|                 CHOOSE_NUM: [CallbackQueryHandler(self.get_jokes),], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('joke', self.entry_point)], | ||||
|             # conversation_timeout=5, | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         keyboard = [[InlineKeyboardButton(str(i), callback_data=str(i)) for i in range(1,11)]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=True, send=True) # at this point every step has been fulfilled | ||||
|         update.message.reply_text("How many jokes?", reply_markup=reply_markup) | ||||
|         return CHOOSE_NUM | ||||
|  | ||||
|  | ||||
|     def get_jokes(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         number = int(query.data) | ||||
|         query.answer() | ||||
|         jokes = self.api.get_random_rising("jokes", number, "text") | ||||
|         # formating | ||||
|         message = "" | ||||
|         for j in jokes: | ||||
|             message += "<b>" + j["title"] + "</b> \n" + j["content"] + "\n\n" | ||||
|         if message == "": | ||||
|             message += "Could not fetch jokes." | ||||
|         query.edit_message_text(text = message, parse_mode = ParseMode.HTML) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| CHOOSE_TOPIC = 0 | ||||
| class Meme(BotFunc): | ||||
|     """Gets the latest memes from reddit""" | ||||
|      | ||||
|     def __init__(self, api, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|         self.api = api | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('meme', self.entry_point)], | ||||
|             states={ | ||||
|                 CHOOSE_TOPIC: [CallbackQueryHandler(self.choose_topic)], | ||||
|                 CHOOSE_NUM :[CallbackQueryHandler(self.get_memes)], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('meme', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|  | ||||
|         keyboard = [ | ||||
|             [InlineKeyboardButton("General", callback_data="memes"),], | ||||
|             [InlineKeyboardButton("Dank memes", callback_data="dankmemes"),], | ||||
|             [InlineKeyboardButton("Maths", callback_data="mathmemes"),], | ||||
|             [InlineKeyboardButton("Physics", callback_data="physicsmemes"),], | ||||
|             [InlineKeyboardButton("Biology", callback_data="biologymemes"),], | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         super().log_activity(read=True, execute=True, send=True) # at this point every step has been fulfilled | ||||
|         update.message.reply_text("What kind of memes?", reply_markup=reply_markup) | ||||
|         return CHOOSE_TOPIC | ||||
|  | ||||
|  | ||||
|     def choose_topic(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         d = query.data | ||||
|         query.answer() | ||||
|  | ||||
|         keyboard = [[InlineKeyboardButton(str(i), callback_data=d + "-" + str(i)) for i in range(1,11)]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text("How many memes?", reply_markup=reply_markup) | ||||
|         return CHOOSE_NUM | ||||
|  | ||||
|  | ||||
|     def get_memes(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         data = query.data.split("-") | ||||
|         query.answer() | ||||
|  | ||||
|         memes = self.api.get_random_rising(data[0], int(data[1]), "photo") | ||||
|         if len(memes) != 0: | ||||
|             for m in memes: | ||||
|                 super().log_activity(read=False, execute=False, send=True) # we just sent an additional message | ||||
|                 update.effective_chat.send_photo(photo = m["image"],caption = m["caption"]) | ||||
|         else: | ||||
|            update.effective_chat.send_message("Sorry, the meme won't yeet.") | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| # class News(BotFunc): | ||||
| #     """Gets the latest news from reddit""" | ||||
|      | ||||
| #     def __init__(self, api, prst): | ||||
| #         super().__init__(prst) | ||||
| #         self.available_commands = {} | ||||
| #         self.api = api | ||||
|  | ||||
|  | ||||
| #     def create_handler(self): | ||||
| #         conv_handler = ConversationHandler( | ||||
| #             entry_points=[CommandHandler('news', self.entry_point)], | ||||
| #             states={ | ||||
| #                 CHOOSE_TOPIC: [CallbackQueryHandler(self.choose_topic)], | ||||
| #                 CHOOSE_NUM :[CallbackQueryHandler(self.get_news)], | ||||
| #             }, | ||||
| #             fallbacks=[CommandHandler('news', self.entry_point)], | ||||
| #         ) | ||||
| #         return conv_handler | ||||
|  | ||||
|  | ||||
| #     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
| #         super().entry_point() | ||||
|  | ||||
| #         keyboard = [ | ||||
| #             [InlineKeyboardButton("World", callback_data="worldnews"),], | ||||
| #             [InlineKeyboardButton("Germany", callback_data="germannews"),], | ||||
| #             [InlineKeyboardButton("France", callback_data="francenews"),], | ||||
| #             [InlineKeyboardButton("Europe", callback_data="eunews"),], | ||||
| #             [InlineKeyboardButton("USA", callback_data="usanews"),], | ||||
| #         ] | ||||
| #         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
| #         update.message.reply_text("What kind of news?", reply_markup=reply_markup) | ||||
| #         return CHOOSE_TOPIC | ||||
|  | ||||
|  | ||||
| #     def choose_topic(self, update: Update, context: CallbackContext) -> None: | ||||
| #         super().entry_point() | ||||
| #         query = update.callback_query | ||||
| #         d = query.data | ||||
| #         query.answer() | ||||
|  | ||||
| #         keyboard = [[InlineKeyboardButton(str(i), callback_data=d + "-" + str(i)) for i in range(1,11)]] | ||||
| #         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
| #         query.edit_message_text("How many entries?", reply_markup=reply_markup) | ||||
| #         return CHOOSE_NUM | ||||
|  | ||||
|  | ||||
| #     def get_news(self, update: Update, context: CallbackContext) -> None: | ||||
| #         query = update.callback_query | ||||
| #         data = query.data.split("-") | ||||
| #         query.answer() | ||||
| #         #try: | ||||
| #         news = self.api.get_top(data[0], data[1], "text") | ||||
| #         # formating | ||||
| #         message = "" | ||||
| #         for j in news: | ||||
| #             message += "<b>" + j["title"] + "</b> \n" + j["content"] + "\n\n" | ||||
| #         if message == "": | ||||
| #             message += "Could not fetch news." | ||||
| #         query.edit_message_text(news, paresemode=ParseMode.HTML) | ||||
| #         return ConversationHandler.END | ||||
| @@ -1,61 +1,61 @@ | ||||
| from .template import * | ||||
|  | ||||
|  | ||||
| SEARCH, MORE = range(2) | ||||
| class Search(BotFunc): | ||||
|     """Browse the web for a topic.""" | ||||
|      | ||||
|     def __init__(self, api, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|         self.api = api | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('search', self.entry_point)], | ||||
|             states={ | ||||
|                 SEARCH: [MessageHandler(Filters.text, self.get_results),], | ||||
|                 MORE: [CallbackQueryHandler(self.show_more, pattern="^more$"),], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('search', self.entry_point)], | ||||
|             conversation_timeout=20, | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         update.message.reply_text("What are we searching?") | ||||
|         return SEARCH | ||||
|  | ||||
|  | ||||
|     def get_results(self, update: Update, context: CallbackContext) -> None: | ||||
|         search = update.message.text | ||||
|         results = self.api.get_result(search) | ||||
|         keyboard = [[InlineKeyboardButton("More!", callback_data="more")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|          | ||||
|         # formating | ||||
|         self.results = results | ||||
|         if results: | ||||
|             first = results[0] | ||||
|             message = first["text"] + "\n(" + first["url"] + ")\n\n" | ||||
|         else: | ||||
|             message = "No results for search query." | ||||
|         update.message.reply_text(text = message, reply_markup=reply_markup) | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|         return MORE | ||||
|      | ||||
|  | ||||
|     def show_more(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         message = "" | ||||
|         for r in self.results: | ||||
|             message += r["text"] + "\n(" + r["url"] + ")\n\n" | ||||
|  | ||||
|         query.edit_message_text(message) | ||||
|         super().log_activity(read = False, execute = False, send = True) | ||||
| from .template import * | ||||
|  | ||||
|  | ||||
| SEARCH, MORE = range(2) | ||||
| class Search(BotFunc): | ||||
|     """Browse the web for a topic.""" | ||||
|      | ||||
|     def __init__(self, api, db): | ||||
|         super().__init__(db) | ||||
|         self.available_commands = {} | ||||
|         self.api = api | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('search', self.entry_point)], | ||||
|             states={ | ||||
|                 SEARCH: [MessageHandler(Filters.text, self.get_results),], | ||||
|                 MORE: [CallbackQueryHandler(self.show_more, pattern="^more$"),], | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('search', self.entry_point)], | ||||
|             conversation_timeout=20, | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         update.message.reply_text("What are we searching?") | ||||
|         return SEARCH | ||||
|  | ||||
|  | ||||
|     def get_results(self, update: Update, context: CallbackContext) -> None: | ||||
|         search = update.message.text | ||||
|         results = self.api.get_result(search) | ||||
|         keyboard = [[InlineKeyboardButton("More!", callback_data="more")]] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|          | ||||
|         # formating | ||||
|         self.results = results | ||||
|         if results: | ||||
|             first = results[0] | ||||
|             message = first["text"] + "\n(" + first["url"] + ")\n\n" | ||||
|         else: | ||||
|             message = "No results for search query." | ||||
|         update.message.reply_text(text = message, reply_markup=reply_markup) | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|         return MORE | ||||
|      | ||||
|  | ||||
|     def show_more(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|  | ||||
|         message = "" | ||||
|         for r in self.results: | ||||
|             message += r["text"] + "\n(" + r["url"] + ")\n\n" | ||||
|  | ||||
|         query.edit_message_text(message) | ||||
|         super().log_activity(read = False, execute = False, send = True) | ||||
|         return ConversationHandler.END | ||||
| @@ -1,105 +1,106 @@ | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
| import requests | ||||
| import socket | ||||
| import numpy as np | ||||
| import os | ||||
| import json | ||||
|  | ||||
|  | ||||
| FIRST = 1 | ||||
|  | ||||
| class Status(BotFunc): | ||||
|     """Shows a short status of the program.""" | ||||
|      | ||||
|     def __init__(self, name, version, db): | ||||
|         super().__init__(db) | ||||
|         self.start_time = datetime.datetime.now() | ||||
|         self.name = name | ||||
|         self.version = version | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('status', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.send_log, pattern="^full$"), | ||||
|                 ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('status', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("And the log?", callback_data="full"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         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 | ||||
|             with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: | ||||
|                 s.connect(('8.8.8.8', 80)) | ||||
|                 (addr, port) = s.getsockname() | ||||
|             local_ips = addr | ||||
|         except: | ||||
|             ip = "not fetchable" | ||||
|             local_ips = "not fetchable" | ||||
|  | ||||
|         message += "Status: Running 🟢\n" | ||||
|         message += "Uptime: `" + delta[:delta.rfind(".")] + "`\n" | ||||
|         # message += "Reboots: `" + str(self.persistence["global"]["reboots"]) + "`\n" | ||||
|         message += "IP (public): `" + ip + "`\n" | ||||
|         message += "IP (private): `" + str(local_ips) + "`\n" | ||||
|         u = str(self.get_ngrok_url()) | ||||
|         message += "URL: [" + u + "](" + u + ")\n" | ||||
|          | ||||
|         tot_r = self.db.chats.select().where(self.db.chats.read == True).count() | ||||
|         message += "Total messages read: `{}`\n".format(tot_r) | ||||
|  | ||||
|         tot_s = self.db.chats.select().where(self.db.chats.send == True).count() | ||||
|         message += "Total messages sent: `{}`\n".format(tot_s) | ||||
|  | ||||
|         tot_e = self.db.chats.select().where(self.db.chats.execute == True).count() | ||||
|         message += "Total commands executed: `{}`\n".format(tot_e) | ||||
|  | ||||
|         if update.message: | ||||
|             update.message.reply_text(message, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN) | ||||
|         else: | ||||
|             update._effective_chat.send_message(message, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN) | ||||
|          | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def send_log(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         wanted = query.data.replace("status-","") | ||||
|         query.answer() | ||||
|         with open("persistence/server.log") as l: | ||||
|             query.message.reply_document(l) | ||||
|  | ||||
|         super().log_activity(read = False, execute = False, send = True) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def get_ngrok_url(self): | ||||
|         try: | ||||
|             url = "http://localhost:4040/api/tunnels/" | ||||
|             res = requests.get(url) | ||||
|             res_unicode = res.content.decode("utf-8") | ||||
|             res_json = json.loads(res_unicode) | ||||
|             for i in res_json["tunnels"]: | ||||
|                 if i['name'] == 'command_line': | ||||
|                     return i['public_url'] | ||||
|                     break | ||||
|         except: | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
| import requests | ||||
| import socket | ||||
| import numpy as np | ||||
| import os | ||||
| import json | ||||
|  | ||||
|  | ||||
| FIRST = 1 | ||||
|  | ||||
| class Status(BotFunc): | ||||
|     """Shows a short status of the program.""" | ||||
|      | ||||
|     def __init__(self, name, version, db): | ||||
|         super().__init__(db) | ||||
|         self.start_time = datetime.datetime.now() | ||||
|         self.name = name | ||||
|         self.version = version | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('status', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.send_log, pattern="^full$"), | ||||
|                 ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('status', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("And the log?", callback_data="full"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|  | ||||
|         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 | ||||
|             with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: | ||||
|                 s.connect(('8.8.8.8', 80)) | ||||
|                 (addr, port) = s.getsockname() | ||||
|             local_ips = addr | ||||
|         except: | ||||
|             ip = "not fetchable" | ||||
|             local_ips = "not fetchable" | ||||
|  | ||||
|         message += "Status: Running 🟢\n" | ||||
|         message += "Uptime: `" + delta[:delta.rfind(".")] + "`\n" | ||||
|         # message += "Reboots: `" + str(self.persistence["global"]["reboots"]) + "`\n" | ||||
|         message += "IP (public): `" + ip + "`\n" | ||||
|         message += "IP (private): `" + str(local_ips) + "`\n" | ||||
|         u = str(self.get_ngrok_url()) | ||||
|         message += "URL: [" + u + "](" + u + ")\n" | ||||
|          | ||||
|         # TODO new DB | ||||
|         tot_r = self.db.chats.select().where(self.db.chats.read == True).count() | ||||
|         message += "Total messages read: `{}`\n".format(tot_r) | ||||
|  | ||||
|         tot_s = self.db.chats.select().where(self.db.chats.send == True).count() | ||||
|         message += "Total messages sent: `{}`\n".format(tot_s) | ||||
|  | ||||
|         tot_e = self.db.chats.select().where(self.db.chats.execute == True).count() | ||||
|         message += "Total commands executed: `{}`\n".format(tot_e) | ||||
|  | ||||
|         if update.message: | ||||
|             update.message.reply_text(message, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN) | ||||
|         else: | ||||
|             update._effective_chat.send_message(message, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN) | ||||
|          | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def send_log(self, update: Update, context: CallbackContext) -> None: | ||||
|         query = update.callback_query | ||||
|         wanted = query.data.replace("status-","") | ||||
|         query.answer() | ||||
|         with open("persistence/server.log") as l: | ||||
|             query.message.reply_document(l) | ||||
|  | ||||
|         super().log_activity(read = False, execute = False, send = True) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def get_ngrok_url(self): | ||||
|         try: | ||||
|             url = "http://localhost:4040/api/tunnels/" | ||||
|             res = requests.get(url) | ||||
|             res_unicode = res.content.decode("utf-8") | ||||
|             res_json = json.loads(res_unicode) | ||||
|             for i in res_json["tunnels"]: | ||||
|                 if i['name'] == 'command_line': | ||||
|                     return i['public_url'] | ||||
|                     break | ||||
|         except: | ||||
|             return "Not available" | ||||
| @@ -1,44 +1,43 @@ | ||||
| import logging | ||||
| import datetime | ||||
| from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ParseMode | ||||
| from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext, MessageHandler, Filters | ||||
| from telegram.ext import ( | ||||
|     Updater, | ||||
|     CommandHandler, | ||||
|     CallbackQueryHandler, | ||||
|     ConversationHandler, | ||||
|     CallbackContext, | ||||
| ) | ||||
|  | ||||
|  | ||||
| import datetime | ||||
|  | ||||
|  | ||||
| class BotFunc(): | ||||
|     """Base class for a specific bot-functionality""" | ||||
|     def __init__(self, db): | ||||
|         self.logger = logging.getLogger(__name__) | ||||
|         self.db = db | ||||
|  | ||||
|  | ||||
|     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 entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         if update.message.text: | ||||
|             self.logger.info("Chat said: {}".format(update.message.text)) | ||||
|         else: | ||||
|             self.logger.info("Chat said: {}".format(update.message)) | ||||
|  | ||||
| import logging | ||||
| from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ParseMode | ||||
| from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext, MessageHandler, Filters | ||||
| from telegram.ext import ( | ||||
|     Updater, | ||||
|     CommandHandler, | ||||
|     CallbackQueryHandler, | ||||
|     ConversationHandler, | ||||
|     CallbackContext, | ||||
| ) | ||||
|  | ||||
|  | ||||
| import datetime | ||||
|  | ||||
|  | ||||
| class BotFunc(): | ||||
|     """Base class for a specific bot-functionality""" | ||||
|     def __init__(self, db): | ||||
|         self.logger = logging.getLogger(__name__) | ||||
|         self.db = db | ||||
|  | ||||
|  | ||||
|     # 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 entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         if update.message.text: | ||||
|             self.logger.info("Chat said: {}".format(update.message.text)) | ||||
|         else: | ||||
|             self.logger.info("Chat said: {}".format(update.message)) | ||||
|  | ||||
|   | ||||
| @@ -1,117 +1,117 @@ | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
|  | ||||
| FIRST = 1 | ||||
|  | ||||
| class Weather(BotFunc): | ||||
|     """Shows a weatherforecast for a given location""" | ||||
|     def __init__(self, api, db): | ||||
|         """initialize api and persistence""" | ||||
|         super().__init__(db) | ||||
|         self.api = api | ||||
|         self.city = "" | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         """returns the handlers with button-logic""" | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('weather', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.choose_city, pattern="^city-"), | ||||
|                     CallbackQueryHandler(self.choose_time, pattern="^time-"), | ||||
|                 ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('weather', self.entry_point)], | ||||
|         ) | ||||
|  | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         """Reacts the call of the command. Prints the first buttons""" | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("Zürich", callback_data="city-zurich"), | ||||
|                 InlineKeyboardButton("Freiburg", callback_data="city-freiburg"), | ||||
|                 InlineKeyboardButton("Mulhouse", callback_data="city-mulhouse"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         if update.message: | ||||
|             update.message.reply_text("Which city?", reply_markup=reply_markup) | ||||
|         else: | ||||
|             update.callback_query.edit_message_text("Which city", reply_markup=reply_markup) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def choose_city(self, update: Update, context: CallbackContext) -> None: | ||||
|         """Prompt same text & keyboard as `start` does but not as new message""" | ||||
|         # Get CallbackQuery from Update | ||||
|         query = update.callback_query | ||||
|         data = query.data | ||||
|         self.city = data.replace("city-","") | ||||
|         query.answer() | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("Now", callback_data="time-now"), | ||||
|                 InlineKeyboardButton("Tomorrow", callback_data="time-tomorrow"), | ||||
|                 InlineKeyboardButton("7 days", callback_data="time-7"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text( | ||||
|             text = "Which time?", reply_markup=reply_markup | ||||
|         ) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def choose_time(self, update: Update, context: CallbackContext) -> None: | ||||
|         """Show new choice of buttons""" | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         forecast_time = query.data.replace("time-","") | ||||
|         weather = self.get_weather(self.city, forecast_time) | ||||
|         query.edit_message_text( | ||||
|             text = "Weather: \n\n" + weather, | ||||
|             parse_mode = ParseMode.HTML | ||||
|         ) | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def get_weather(self, city, forecast_time) -> None: | ||||
|         """get the weather that matches the given params""" | ||||
|         locations = {"freiburg": [47.9990, 7.8421], "zurich": [47.3769, 8.5417], "mulhouse": [47.7508, 7.3359]} | ||||
|  | ||||
|         city = locations[city] | ||||
|          | ||||
|         categories = {"Clouds": "☁", "Rain": "🌧", "Thunderstorm": "🌩", "Drizzle": ":droplet:", "Snow": "❄", "Clear": "☀", "Mist": "🌫", "Smoke": "Smoke", "Haze": "Haze", "Dust": "Dust", "Fog": "Fog", "Sand": "Sand", "Dust": "Dust", "Ash": "Ash", "Squall": "Squall", "Tornado": "Tornado",} | ||||
|         days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] | ||||
|         today = datetime.datetime.today().weekday() | ||||
|         weather = self.api.show_weather(city) | ||||
|         message = "" | ||||
|         if forecast_time == "now" or forecast_time == "7": | ||||
|             now = weather.pop(0) | ||||
|             message += "<b>Now:</b> " + categories[now["short"]] + "\n" | ||||
|             message += "🌡" + str(now["temps"][0]) + "°\n\n" | ||||
|             tod = weather.pop(0) | ||||
|             message += "<b>" + "Today" + ":</b> " + categories[tod["short"]] + "\n" | ||||
|             message += "🌡 ❄ " + str(tod["temps"][0]) + "° , 🌡 🔥 " + str(tod["temps"][1]) + "°\n\n" | ||||
|  | ||||
|         if forecast_time == "tomorrow" or forecast_time == "7": | ||||
|             if forecast_time == "tomorrow": # previous statement was not executed: tomorrow is at weather[2] | ||||
|                 tom = weather.pop(2) | ||||
|             else: | ||||
|                 tom = weather.pop(0) | ||||
|             message += "<b>" + "Tomorrow" + ":</b> " + categories[tom["short"]] + "\n" | ||||
|             message += "🌡 ❄ " + str(tom["temps"][0]) + "° , 🌡 🔥 " + str(tom["temps"][1]) + "°\n\n" | ||||
|  | ||||
|         if forecast_time == "7": | ||||
|             for i, day in enumerate(weather): | ||||
|                 message += "<b>" + days[(today + i + 2) % 7] + ":</b> " + categories[day["short"]] + "\n" | ||||
|                 message += "🌡 ❄ " + str(day["temps"][0]) + "° , 🌡 🔥 " + str(day["temps"][1]) + "°\n\n" | ||||
|  | ||||
|         return message | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
|  | ||||
| FIRST = 1 | ||||
|  | ||||
| class Weather(BotFunc): | ||||
|     """Shows a weatherforecast for a given location""" | ||||
|     def __init__(self, api, db): | ||||
|         """initialize api and persistence""" | ||||
|         super().__init__(db) | ||||
|         self.api = api | ||||
|         self.city = "" | ||||
|  | ||||
|  | ||||
|     def create_handler(self): | ||||
|         """returns the handlers with button-logic""" | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('weather', self.entry_point)], | ||||
|             states={ | ||||
|                 FIRST: [ | ||||
|                     CallbackQueryHandler(self.choose_city, pattern="^city-"), | ||||
|                     CallbackQueryHandler(self.choose_time, pattern="^time-"), | ||||
|                 ] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('weather', self.entry_point)], | ||||
|         ) | ||||
|  | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         """Reacts the call of the command. Prints the first buttons""" | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("Zürich", callback_data="city-zurich"), | ||||
|                 InlineKeyboardButton("Freiburg", callback_data="city-freiburg"), | ||||
|                 InlineKeyboardButton("Mulhouse", callback_data="city-mulhouse"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         if update.message: | ||||
|             update.message.reply_text("Which city?", reply_markup=reply_markup) | ||||
|         else: | ||||
|             update.callback_query.edit_message_text("Which city", reply_markup=reply_markup) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def choose_city(self, update: Update, context: CallbackContext) -> None: | ||||
|         """Prompt same text & keyboard as `start` does but not as new message""" | ||||
|         # Get CallbackQuery from Update | ||||
|         query = update.callback_query | ||||
|         data = query.data | ||||
|         self.city = data.replace("city-","") | ||||
|         query.answer() | ||||
|         keyboard = [ | ||||
|             [ | ||||
|                 InlineKeyboardButton("Now", callback_data="time-now"), | ||||
|                 InlineKeyboardButton("Tomorrow", callback_data="time-tomorrow"), | ||||
|                 InlineKeyboardButton("7 days", callback_data="time-7"), | ||||
|             ] | ||||
|         ] | ||||
|         reply_markup = InlineKeyboardMarkup(keyboard) | ||||
|         query.edit_message_text( | ||||
|             text = "Which time?", reply_markup=reply_markup | ||||
|         ) | ||||
|         return FIRST | ||||
|  | ||||
|  | ||||
|     def choose_time(self, update: Update, context: CallbackContext) -> None: | ||||
|         """Show new choice of buttons""" | ||||
|         query = update.callback_query | ||||
|         query.answer() | ||||
|         forecast_time = query.data.replace("time-","") | ||||
|         weather = self.get_weather(self.city, forecast_time) | ||||
|         query.edit_message_text( | ||||
|             text = "Weather: \n\n" + weather, | ||||
|             parse_mode = ParseMode.HTML | ||||
|         ) | ||||
|         super().log_activity(read = True, execute = True, send = True) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def get_weather(self, city, forecast_time) -> None: | ||||
|         """get the weather that matches the given params""" | ||||
|         locations = {"freiburg": [47.9990, 7.8421], "zurich": [47.3769, 8.5417], "mulhouse": [47.7508, 7.3359]} | ||||
|  | ||||
|         city = locations[city] | ||||
|          | ||||
|         categories = {"Clouds": "☁", "Rain": "🌧", "Thunderstorm": "🌩", "Drizzle": ":droplet:", "Snow": "❄", "Clear": "☀", "Mist": "🌫", "Smoke": "Smoke", "Haze": "Haze", "Dust": "Dust", "Fog": "Fog", "Sand": "Sand", "Dust": "Dust", "Ash": "Ash", "Squall": "Squall", "Tornado": "Tornado",} | ||||
|         days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] | ||||
|         today = datetime.datetime.today().weekday() | ||||
|         weather = self.api.show_weather(city) | ||||
|         message = "" | ||||
|         if forecast_time == "now" or forecast_time == "7": | ||||
|             now = weather.pop(0) | ||||
|             message += "<b>Now:</b> " + categories[now["short"]] + "\n" | ||||
|             message += "🌡" + str(now["temps"][0]) + "°\n\n" | ||||
|             tod = weather.pop(0) | ||||
|             message += "<b>" + "Today" + ":</b> " + categories[tod["short"]] + "\n" | ||||
|             message += "🌡 ❄ " + str(tod["temps"][0]) + "° , 🌡 🔥 " + str(tod["temps"][1]) + "°\n\n" | ||||
|  | ||||
|         if forecast_time == "tomorrow" or forecast_time == "7": | ||||
|             if forecast_time == "tomorrow": # previous statement was not executed: tomorrow is at weather[2] | ||||
|                 tom = weather.pop(2) | ||||
|             else: | ||||
|                 tom = weather.pop(0) | ||||
|             message += "<b>" + "Tomorrow" + ":</b> " + categories[tom["short"]] + "\n" | ||||
|             message += "🌡 ❄ " + str(tom["temps"][0]) + "° , 🌡 🔥 " + str(tom["temps"][1]) + "°\n\n" | ||||
|  | ||||
|         if forecast_time == "7": | ||||
|             for i, day in enumerate(weather): | ||||
|                 message += "<b>" + days[(today + i + 2) % 7] + ":</b> " + categories[day["short"]] + "\n" | ||||
|                 message += "🌡 ❄ " + str(day["temps"][0]) + "° , 🌡 🔥 " + str(day["temps"][1]) + "°\n\n" | ||||
|  | ||||
|         return message | ||||
|   | ||||
| @@ -1,87 +1,87 @@ | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
| import requests | ||||
|  | ||||
| START, DEST = range(2) | ||||
|  | ||||
| class Zvv(BotFunc): | ||||
|     """Connects to the swiss travel-api to get public transport routes""" | ||||
|  | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|         self.start = "" | ||||
|         self.dest = "" | ||||
|         pass | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('zvv', self.entry_point)], | ||||
|             states={ | ||||
|                 START: [MessageHandler(Filters.text, callback=self.get_start)], | ||||
|                 DEST: [MessageHandler(Filters.text, callback=self.get_dest)] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('zvv', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         update.message.reply_text("What is the start point?") | ||||
|         return START | ||||
|  | ||||
|  | ||||
|     def get_start(self, update: Update, context: CallbackContext) -> None: | ||||
|         loc = update.message.text | ||||
|         self.start = loc | ||||
|         update.message.reply_text("Ok. Going from " + loc + ", what is the destination?") | ||||
|         return DEST | ||||
|  | ||||
|  | ||||
|     def get_dest(self, update: Update, context: CallbackContext) -> None: | ||||
|         loc = update.message.text | ||||
|         self.dest = loc | ||||
|         route = self.get_result() | ||||
|         update.message.reply_text("Here are the routes I've got:\n" + route) | ||||
|         super().log_activity(read=True, execute=True, send=True) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def get_result(self): | ||||
|         url = "http://transport.opendata.ch/v1/connections" | ||||
|  | ||||
|         start = self.start | ||||
|         dest = self.dest | ||||
|  | ||||
|         data = {"from" : start, "to" : dest, "limit" : 2} | ||||
|         try: | ||||
|             routes = requests.get(url, params=data).json() | ||||
|             result = routes["connections"] | ||||
|             text = result[0]["from"]["station"]["name"] + " ⏩ " + result[0]["to"]["station"]["name"] + "\n\n" | ||||
|             for con in result: | ||||
|                 text += "Start: " + datetime.datetime.fromtimestamp(int(con["from"]["departureTimestamp"])).strftime("%d/%m - %H:%M") + "\n" | ||||
|                 text += "🏁 " + datetime.datetime.fromtimestamp(int(con["to"]["arrivalTimestamp"])).strftime("%d/%m - %H:%M") + "\n" | ||||
|                 text += "⏳ " + con["duration"] + "\n" | ||||
|                 text += "🗺️ Route:\n" | ||||
|  | ||||
|                 for step in con["sections"]: | ||||
|                     if step["journey"] != None: | ||||
|                         text += step["journey"]["passList"][0]["station"]["name"] + " (" + datetime.datetime.fromtimestamp(int(step["journey"]["passList"][0]["departureTimestamp"])).strftime("%H:%M") + ")\n" | ||||
|  | ||||
|                         text += "➡️ Linie " + self.number_to_emoji(step["journey"]["number"]) + "\n" | ||||
|  | ||||
|                         text += step["journey"]["passList"][-1]["station"]["name"] + " (" + datetime.datetime.fromtimestamp(int(step["journey"]["passList"][-1]["arrivalTimestamp"])).strftime("%H:%M") +")\n" | ||||
|                     else: | ||||
|                         text += "Walk." | ||||
|                 text += "\n" | ||||
|             return text | ||||
|         except: | ||||
|             return "Invalid api call." | ||||
|  | ||||
|     def number_to_emoji(self, number): | ||||
|         out = "" | ||||
|         numbers = ["0️⃣","1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣","8️⃣","9️⃣"] | ||||
|         for i in str(number): | ||||
|             out += numbers[int(i)] | ||||
| from .template import * | ||||
|  | ||||
| import datetime | ||||
| import requests | ||||
|  | ||||
| START, DEST = range(2) | ||||
|  | ||||
| class Zvv(BotFunc): | ||||
|     """Connects to the swiss travel-api to get public transport routes""" | ||||
|  | ||||
|     def __init__(self, db): | ||||
|         super().__init__(db) | ||||
|         self.start = "" | ||||
|         self.dest = "" | ||||
|         pass | ||||
|  | ||||
|     def create_handler(self): | ||||
|         conv_handler = ConversationHandler( | ||||
|             entry_points=[CommandHandler('zvv', self.entry_point)], | ||||
|             states={ | ||||
|                 START: [MessageHandler(Filters.text, callback=self.get_start)], | ||||
|                 DEST: [MessageHandler(Filters.text, callback=self.get_dest)] | ||||
|             }, | ||||
|             fallbacks=[CommandHandler('zvv', self.entry_point)], | ||||
|         ) | ||||
|         return conv_handler | ||||
|  | ||||
|  | ||||
|     def entry_point(self, update: Update, context: CallbackContext) -> None: | ||||
|         super().entry_point(update, context) | ||||
|         update.message.reply_text("What is the start point?") | ||||
|         return START | ||||
|  | ||||
|  | ||||
|     def get_start(self, update: Update, context: CallbackContext) -> None: | ||||
|         loc = update.message.text | ||||
|         self.start = loc | ||||
|         update.message.reply_text("Ok. Going from " + loc + ", what is the destination?") | ||||
|         return DEST | ||||
|  | ||||
|  | ||||
|     def get_dest(self, update: Update, context: CallbackContext) -> None: | ||||
|         loc = update.message.text | ||||
|         self.dest = loc | ||||
|         route = self.get_result() | ||||
|         update.message.reply_text("Here are the routes I've got:\n" + route) | ||||
|         super().log_activity(read=True, execute=True, send=True) | ||||
|         return ConversationHandler.END | ||||
|  | ||||
|  | ||||
|     def get_result(self): | ||||
|         url = "http://transport.opendata.ch/v1/connections" | ||||
|  | ||||
|         start = self.start | ||||
|         dest = self.dest | ||||
|  | ||||
|         data = {"from" : start, "to" : dest, "limit" : 2} | ||||
|         try: | ||||
|             routes = requests.get(url, params=data).json() | ||||
|             result = routes["connections"] | ||||
|             text = result[0]["from"]["station"]["name"] + " ⏩ " + result[0]["to"]["station"]["name"] + "\n\n" | ||||
|             for con in result: | ||||
|                 text += "Start: " + datetime.datetime.fromtimestamp(int(con["from"]["departureTimestamp"])).strftime("%d/%m - %H:%M") + "\n" | ||||
|                 text += "🏁 " + datetime.datetime.fromtimestamp(int(con["to"]["arrivalTimestamp"])).strftime("%d/%m - %H:%M") + "\n" | ||||
|                 text += "⏳ " + con["duration"] + "\n" | ||||
|                 text += "🗺️ Route:\n" | ||||
|  | ||||
|                 for step in con["sections"]: | ||||
|                     if step["journey"] != None: | ||||
|                         text += step["journey"]["passList"][0]["station"]["name"] + " (" + datetime.datetime.fromtimestamp(int(step["journey"]["passList"][0]["departureTimestamp"])).strftime("%H:%M") + ")\n" | ||||
|  | ||||
|                         text += "➡️ Linie " + self.number_to_emoji(step["journey"]["number"]) + "\n" | ||||
|  | ||||
|                         text += step["journey"]["passList"][-1]["station"]["name"] + " (" + datetime.datetime.fromtimestamp(int(step["journey"]["passList"][-1]["arrivalTimestamp"])).strftime("%H:%M") +")\n" | ||||
|                     else: | ||||
|                         text += "Walk." | ||||
|                 text += "\n" | ||||
|             return text | ||||
|         except: | ||||
|             return "Invalid api call." | ||||
|  | ||||
|     def number_to_emoji(self, number): | ||||
|         out = "" | ||||
|         numbers = ["0️⃣","1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣","8️⃣","9️⃣"] | ||||
|         for i in str(number): | ||||
|             out += numbers[int(i)] | ||||
|         return str(out) | ||||
							
								
								
									
										136
									
								
								bot/main.py
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								bot/main.py
									
									
									
									
									
								
							| @@ -1,68 +1,68 @@ | ||||
| from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext | ||||
|  | ||||
| from . import api, commands | ||||
|  | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
| class ChatBot(): | ||||
|     """better framwork - unites all functions""" | ||||
|  | ||||
|     def __init__(self, name, version): | ||||
|         """Inits the Bot with a few conf. vars | ||||
|         Args:   -> name:str - Name of the bot | ||||
|                 -> version:str - Version number | ||||
|                 -> hw_commands - dict with commands executable by the clock module | ||||
|                 -> prst:dict - persistence (overloaded dict that writes to json file) | ||||
|                 -> logger - logging object to unify log messages | ||||
|         """ | ||||
|         # added by the launcher, we have self.modules (dict) and persistence and db | ||||
|  | ||||
|         self.name = name | ||||
|         self.version = version | ||||
|          | ||||
|         # Import submodules | ||||
|         self.api_weather = api.weather.WeatherFetch(api.keys.weather_api) | ||||
|         self.api_reddit = api.reddit.RedditFetch(api.keys.reddit_api) | ||||
|         self.api_search = api.search.WebSearch() | ||||
|         self.api_art = api.metmuseum.ArtFetch() | ||||
|         # and so on | ||||
|  | ||||
|         self.telegram = Updater(api.keys.telegram_api, use_context=True) | ||||
|         self.dispatcher = self.telegram.dispatcher | ||||
|         self.commands = commands | ||||
|  | ||||
|  | ||||
|          | ||||
|     def add_commands(self): | ||||
|         # Mark modules as available | ||||
|         db = self.db | ||||
|         self.help_module = self.commands.help.Help(db) | ||||
|         self.sub_modules = { | ||||
|             "weather": self.commands.weather.Weather(self.api_weather, db), | ||||
|             "help" : self.help_module, | ||||
|             "status" : self.commands.status.Status(self.name, self.version, db), | ||||
|             "zvv" : self.commands.zvv.Zvv(db), | ||||
|             "list" : self.commands.lists.Lists(db), | ||||
|             # "alias" : commands.alias.Alias(self.dispatcher, db), | ||||
|             "joke" : self.commands.reddit.Joke(self.api_reddit, db), | ||||
|             "meme" : self.commands.reddit.Meme(self.api_reddit, db), | ||||
|             # "news" : self.commands.reddit.News(self.api_reddit, db), | ||||
|             "search" : self.commands.search.Search(self.api_search, db), | ||||
|             # ... | ||||
|             "plaintext" : self.commands.plaintext.Plain(db) # for handling non-command messages that should simply contribute to statistics | ||||
|             } | ||||
|         # must be a class that has a method create_handler | ||||
|      | ||||
|         for k in self.sub_modules: | ||||
|             self.dispatcher.add_handler(self.sub_modules[k].create_handler()) | ||||
|  | ||||
|         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.add_commands() | ||||
|         self.telegram.start_polling( | ||||
|             poll_interval=0.2, | ||||
|         ) | ||||
|         # self.telegram.idle() | ||||
| from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext | ||||
|  | ||||
| from . import api, commands | ||||
|  | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
| class ChatBot(): | ||||
|     """better framwork - unites all functions""" | ||||
|  | ||||
|     def __init__(self, name, version): | ||||
|         """Inits the Bot with a few conf. vars | ||||
|         Args:   -> name:str - Name of the bot | ||||
|                 -> version:str - Version number | ||||
|                 -> hw_commands - dict with commands executable by the clock module | ||||
|                 -> prst:dict - persistence (overloaded dict that writes to json file) | ||||
|                 -> logger - logging object to unify log messages | ||||
|         """ | ||||
|         # added by the launcher, we have self.modules (dict) and persistence and db | ||||
|  | ||||
|         self.name = name | ||||
|         self.version = version | ||||
|          | ||||
|         # Import submodules | ||||
|         self.api_weather = api.weather.WeatherFetch(api.keys.weather_api) | ||||
|         self.api_reddit = api.reddit.RedditFetch(api.keys.reddit_api) | ||||
|         self.api_search = api.search.WebSearch() | ||||
|         self.api_art = api.metmuseum.ArtFetch() | ||||
|         # and so on | ||||
|  | ||||
|         self.telegram = Updater(api.keys.telegram_api, use_context=True) | ||||
|         self.dispatcher = self.telegram.dispatcher | ||||
|         self.commands = commands | ||||
|  | ||||
|  | ||||
|          | ||||
|     def add_commands(self): | ||||
|         # Mark modules as available | ||||
|         db = self.db | ||||
|         self.help_module = self.commands.help.Help(db) | ||||
|         self.sub_modules = { | ||||
|             "weather": self.commands.weather.Weather(self.api_weather, db), | ||||
|             "help" : self.help_module, | ||||
|             "status" : self.commands.status.Status(self.name, self.version, db), | ||||
|             "zvv" : self.commands.zvv.Zvv(db), | ||||
|             "list" : self.commands.lists.Lists(db), | ||||
|             # "alias" : commands.alias.Alias(self.dispatcher, db), | ||||
|             "joke" : self.commands.reddit.Joke(self.api_reddit, db), | ||||
|             "meme" : self.commands.reddit.Meme(self.api_reddit, db), | ||||
|             # "news" : self.commands.reddit.News(self.api_reddit, db), | ||||
|             "search" : self.commands.search.Search(self.api_search, db), | ||||
|             # ... | ||||
|             "plaintext" : self.commands.plaintext.Plain(db) # for handling non-command messages that should simply contribute to statistics | ||||
|             } | ||||
|         # must be a class that has a method create_handler | ||||
|      | ||||
|         for k in self.sub_modules: | ||||
|             self.dispatcher.add_handler(self.sub_modules[k].create_handler()) | ||||
|  | ||||
|         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.add_commands() | ||||
|         self.telegram.start_polling( | ||||
|             poll_interval=0.2, | ||||
|         ) | ||||
|         # self.telegram.idle() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Remy Moll
					Remy Moll