Better websearch. Readded reddit to bot commands
This commit is contained in:
parent
20a8cb70e1
commit
3ec1744a15
@ -1,4 +1,5 @@
|
||||
from . import google
|
||||
from . import keys
|
||||
from . import reddit
|
||||
from . import weather
|
||||
from . import weather
|
||||
from . import reddit
|
||||
from . import search
|
@ -1,20 +0,0 @@
|
||||
import googlesearch
|
||||
|
||||
|
||||
def query(params):
|
||||
param_string = ""
|
||||
for word in params:
|
||||
param_string += word + "+"
|
||||
param_string = param_string[:-1]
|
||||
search_url = "https://google.com/search?q=" + param_string
|
||||
|
||||
try:
|
||||
res = googlesearch.search(param_string.replace("+"," ") ,num=5,start=0,stop=5)
|
||||
send_string = "Results for <b>" + param_string.replace("+"," ") + "</b>:\n\n"
|
||||
for url in res:
|
||||
send_string += url + "\n\n"
|
||||
send_string += "Search url:\n" + search_url
|
||||
except:
|
||||
send_string = "Search url:\n" + search_url
|
||||
|
||||
return send_string
|
@ -1,50 +1,56 @@
|
||||
import praw
|
||||
try:
|
||||
import bot.api.keys as keys
|
||||
except:
|
||||
import keys
|
||||
|
||||
stream = praw.Reddit(client_id = keys.reddit_id, client_secret = keys.reddit_secret, user_agent=keys.reddit_user_agent)
|
||||
|
||||
def get_top(subreddit, number, return_type="text"):
|
||||
if return_type == "text":
|
||||
message = ""
|
||||
try:
|
||||
for submission in stream.subreddit(subreddit).top(limit=number):
|
||||
if not submission.stickied:
|
||||
message += "<b>" + submission.title + "</b>" + "\n" + submission.selftext + "\n\n\n"
|
||||
return message
|
||||
except:
|
||||
return "Api call failed, sorry"
|
||||
else:
|
||||
images = []
|
||||
try:
|
||||
for submission in stream.subreddit(subreddit).top(limit=number):
|
||||
if not submission.stickied:
|
||||
t = {"image": submission.url, "caption": submission.title}
|
||||
images.append(t)
|
||||
return images
|
||||
except:
|
||||
return ["Api call failed, sorry"]
|
||||
|
||||
|
||||
def get_random_rising(subreddit, number, return_type="text"):
|
||||
if return_type == "text":
|
||||
message = ""
|
||||
try:
|
||||
for submission in stream.subreddit(subreddit).random_rising(limit=number):
|
||||
if not submission.stickied:
|
||||
message += "<b>" + submission.title + "</b>" + "\n" + submission.selftext + "\n\n\n"
|
||||
return message
|
||||
except:
|
||||
return "Api call failed, sorry"
|
||||
else:
|
||||
images = []
|
||||
try:
|
||||
for submission in 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 ["Api call failed, sorry"]
|
||||
|
||||
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 []
|
||||
|
21
bot2/api/search.py
Normal file
21
bot2/api/search.py
Normal file
@ -0,0 +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
|
||||
|
||||
# TODO: this api has more potential. Extract images or quick facts!
|
@ -1,2 +1,2 @@
|
||||
# Placeholder
|
||||
from . import clock, help, weather, status, zvv, lists, alias, plaintext
|
||||
from . import clock, help, weather, status, zvv, lists, alias, plaintext, reddit, search
|
||||
|
@ -1,6 +1,6 @@
|
||||
from .template import *
|
||||
|
||||
FIRST = 1
|
||||
FIRST, EXECUTE = range(2)
|
||||
|
||||
|
||||
class Help(BotFunc):
|
||||
@ -20,6 +20,7 @@ class Help(BotFunc):
|
||||
CallbackQueryHandler(self.choose_specific, pattern="^specific$"),
|
||||
CallbackQueryHandler(self.print_one, pattern='func-'),
|
||||
],
|
||||
EXECUTE :[CallbackQueryHandler(self.execute_now)],
|
||||
# ConversationHandler.TIMEOUT : [
|
||||
# CallbackQueryHandler(self.timeout)
|
||||
# ]
|
||||
@ -46,7 +47,10 @@ class Help(BotFunc):
|
||||
]
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
update.message.reply_text("What exactly do you want?", reply_markup=reply_markup)
|
||||
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
|
||||
|
||||
|
||||
@ -82,13 +86,28 @@ class Help(BotFunc):
|
||||
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 ConversationHandler.END
|
||||
|
||||
return ConversationHandler.END #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].callback
|
||||
func.callback(update, context)
|
||||
return FIRST
|
||||
|
||||
def timeout(self, update: Update, context: CallbackContext) -> None:
|
||||
"""For dying conversation. Currently unused."""
|
||||
|
177
bot2/commands/reddit.py
Normal file
177
bot2/commands/reddit.py
Normal file
@ -0,0 +1,177 @@
|
||||
from .template import *
|
||||
|
||||
|
||||
CHOOSE_NUM = 1
|
||||
class Joke(BotFunc):
|
||||
"""Tells a joke 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('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()
|
||||
keyboard = [[InlineKeyboardButton(str(i), callback_data=str(i)) for i in range(1,11)]]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
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, prst):
|
||||
super().__init__(prst)
|
||||
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:
|
||||
super().entry_point()
|
||||
|
||||
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)
|
||||
update.message.reply_text("What kind of memes?", 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 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:
|
||||
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
|
58
bot2/commands/search.py
Normal file
58
bot2/commands/search.py
Normal file
@ -0,0 +1,58 @@
|
||||
from .template import *
|
||||
|
||||
|
||||
SEARCH, MORE = range(2)
|
||||
class Search(BotFunc):
|
||||
"""Browse the web for a topic."""
|
||||
|
||||
def __init__(self, api, prst):
|
||||
super().__init__(prst)
|
||||
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.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
|
||||
first = results[0]
|
||||
message = first["text"] + "\n(" + first["url"] + ")\n"
|
||||
|
||||
update.message.reply_text(text = message, reply_markup=reply_markup)
|
||||
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"
|
||||
|
||||
query.edit_message_text(message)
|
||||
return ConversationHandler.END
|
@ -34,7 +34,6 @@ class Status(BotFunc):
|
||||
|
||||
def entry_point(self, update: Update, context: CallbackContext) -> None:
|
||||
super().entry_point()
|
||||
user = update.message.from_user
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("And the log?", callback_data="full"),
|
||||
@ -72,7 +71,10 @@ class Status(BotFunc):
|
||||
tot_e = np.array(self.persistence["bot"]["execute_activity"]["count"]).sum()
|
||||
message += "Commands executed `" + str(tot_e) + "`\n"
|
||||
|
||||
update.message.reply_text(message, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN)
|
||||
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)
|
||||
return FIRST
|
||||
|
||||
|
||||
|
19
bot2/main.py
19
bot2/main.py
@ -21,7 +21,8 @@ class ChatBot():
|
||||
self.persistence = prst
|
||||
# Import submodules
|
||||
self.api_weather = api.weather.WeatherFetch(api.keys.weather_api)
|
||||
# self.reddit_api = api.reddit.RedditFetch()
|
||||
self.api_reddit = api.reddit.RedditFetch(api.keys.reddit_api)
|
||||
self.api_search = api.search.WebSearch()
|
||||
# and so on
|
||||
|
||||
self.telegram = Updater(api.keys.telegram_api, use_context=True)
|
||||
@ -37,17 +38,15 @@ class ChatBot():
|
||||
"status" : self.commands.status.Status(name, version, prst),
|
||||
"zvv" : self.commands.zvv.Zvv(prst),
|
||||
"list" : self.commands.lists.Lists(prst),
|
||||
#"alias" : commands.alias.Alias(self.dispatcher, prst),
|
||||
# "alias" : commands.alias.Alias(self.dispatcher, prst),
|
||||
"joke" : self.commands.reddit.Joke(self.api_reddit, prst),
|
||||
"meme" : self.commands.reddit.Meme(self.api_reddit, prst),
|
||||
# "news" : self.commands.reddit.News(self.api_reddit, prst),
|
||||
"search" : self.commands.search.Search(self.api_search, prst),
|
||||
|
||||
|
||||
"plaintext" : self.commands.plaintext.Plain(prst) # for handling non-command messages that should simply contribute to statistics
|
||||
}
|
||||
|
||||
# "events" : self.bot_print_events,
|
||||
# "wikipedia" : self.bot_show_wikipedia,
|
||||
# "cronjob" : self.bot_cronjob,
|
||||
# "joke" : self.bot_tell_joke,
|
||||
# "meme" : self.bot_send_meme,
|
||||
# "news" : self.bot_send_news,
|
||||
# }
|
||||
# must be a class that has a method create_handler
|
||||
|
||||
def add_commands(self):
|
||||
|
@ -41,12 +41,13 @@ class Launcher():
|
||||
self.dashboard_module = dashboard.main.DashBoard(host_ip="0.0.0.0", prst=self.persistence)
|
||||
|
||||
self.modules = {
|
||||
"clock" : self.clock_module,
|
||||
"bot" : self.bot_module,
|
||||
"clock" : self.clock_module,
|
||||
"dashboard" : self.dashboard_module,
|
||||
}
|
||||
|
||||
for module in self.modules.values():
|
||||
self.logger.info("Starting module "+ module.__class__.__name__)
|
||||
module.modules = self.modules
|
||||
module.start()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user