Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

N/message interface #216

Merged
merged 5 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions steely/message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# TODO(iandioch): Migrate to python3.7 so we can annotate this with @dataclass
class SteelyMessage:
"""Class containing information about a single activity in a single channel.
Usually means a message with text was sent, but also could have been an
image sent (with no associated text message), etc."""

author_id: str
thread_id: str
thread_type: str
text: str
# TODO(iandioch): Add image_id.
38 changes: 21 additions & 17 deletions steely/plugins/letterboxd/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from plugin import create_plugin, PluginManager
from message import SteelyMessage
from utils import new_database
from tinydb import Query
from paths import CONFIG
Expand Down Expand Up @@ -63,48 +64,51 @@ def plugin_setup():


@plugin.listen(command='nw [username]')
def root_command(bot, author_id, message, thread_id, thread_type, **kwargs):
user = USERDB.get(USER.id == author_id)
def root_command(bot, message: SteelyMessage, **kwargs):
user = USERDB.get(USER.id == message.author_id)
if 'username' in kwargs:
username = kwargs['username']
elif user:
username = user['username']
else:
bot.sendMessage(f'include username please or use `/nw set`',
thread_id=thread_id, thread_type=thread_type)
thread_id=message.thread_id,
thread_type=message.thread_type)
return

title, date_str, url = get_most_recent_film(username)
if title is None:
bot.sendMessage(f'Could not load most recent film for {username}.',
thread_id=thread_id, thread_type=thread_type)
thread_id=message.thread_id,
thread_type=message.thread_type)
return

bot.sendMessage(f"{username} added {italic(title)} on {date_str}\n{url}",
thread_id=thread_id, thread_type=thread_type)
thread_id=message.thread_id,
thread_type=message.thread_type)


@plugin.listen(command='nw set <username>')
def set_command(bot, author_id, message, thread_id, thread_type, **kwargs):
def set_command(bot, message: SteelyMessage, **kwargs):
if 'username' not in kwargs or not len(kwargs['username']):
bot.sendMessage('no username provided', thread_id=thread_id,
thread_type=thread_type)
bot.sendMessage('no username provided', thread_id=message.thread_id,
thread_type=message.thread_type)
return
username = kwargs['username']
if not USERDB.search(USER.id == author_id):
USERDB.insert({'id': author_id, 'username': username})
if not USERDB.search(USER.id == message.author_id):
USERDB.insert({'id': message.author_id, 'username': username})
bot.sendMessage('good egg, you\'re now {}'.format(username),
thread_id=thread_id,
thread_type=thread_type)
thread_id=message.thread_id,
thread_type=message.thread_type)
else:
USERDB.update({'username': username}, USER.id == author_id)
USERDB.update({'username': username}, USER.id == message.author_id)
bot.sendMessage('updated egg, you\'re now {}'.format(username),
thread_id=thread_id,
thread_type=thread_type)
thread_id=message.thread_id,
thread_type=message.thread_type)


@plugin.listen(command='nw help')
def help_command(bot, author_id, message, thread_id, thread_type, **kwargs):
def help_command(bot, message: SteelyMessage, **kwargs):
bot.sendMessage(plugin.help, thread_id=thread_id, thread_type=thread_type)
bot.sendMessage('\n'.join(("/" + command) for command in plugin.commands),
thread_id=thread_id, thread_type=thread_type)
thread_id=message.thread_id, thread_type=message.thread_type)
52 changes: 32 additions & 20 deletions steely/steely_telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from vapor import vapor
from utils import list_plugins
from plugin import PluginManager
from message import SteelyMessage
import config
import copy
import imp
import os
import random
Expand Down Expand Up @@ -62,20 +64,22 @@ def parse_command_message(message):
clean_command = command.split('@')[0].lower().strip()
return clean_command, message

def run_plugin(self, author_id, message, thread_id, thread_type, **kwargs):
parsed_message = self.parse_command_message(message)
def run_plugin(self, message: SteelyMessage):
parsed_message = self.parse_command_message(message.text)
if parsed_message is None:
return
command, message = parsed_message
command, rest_of_message = parsed_message

# Run plugins following SEP1 interface.
full_message = '{} {}'.format(command, message)
matched_command, plugin, args = PluginManager.get_listener_for_command(full_message)
full_message = '{} {}'.format(command, rest_of_message)
matched_command, plugin, args = PluginManager.get_listener_for_command(
full_message)
if matched_command is not None:
passed_kwargs = kwargs.copy()
passed_kwargs.update(args)
passed_message = copy.copy(message)
passed_message.text = full_message[len(matched_command) + 1:]
thread = threading.Thread(target=plugin,
args=(self, author_id, full_message[len(matched_command)+1:], thread_id, thread_type), kwargs=passed_kwargs)
args=(self, passed_message),
kwargs=args)
thread.deamon = True
thread.start()

Expand All @@ -84,34 +88,42 @@ def run_plugin(self, author_id, message, thread_id, thread_type, **kwargs):
return
plugin = self.plugins[command]
thread = threading.Thread(target=plugin.main,
args=(self, author_id, message, thread_id, thread_type), kwargs=kwargs)
args=(self,
message.author_id,
message.text,
message.thread_id,
message.thread_type),
kwargs={})
thread.deamon = True
thread.start()

def run_non_plugins(self, author_id, message, thread_id, thread_type, **kwargs):
def run_non_plugins(self, message: SteelyMessage):
for plugin in self.non_plugins:
thread = threading.Thread(target=plugin.main,
args=(self, author_id, message, thread_id, thread_type), kwargs=kwargs)
args=(self,
message.author_id,
message.text,
message.thread_id,
message.thread_type),
kwargs={})
thread.deamon = True
thread.start()

for plugin in PluginManager.get_passive_listeners():
thread = threading.Thread(target=plugin,
args=(self, author_id, message, thread_id, thread_type), kwargs=kwargs)
args=(self, message),
kwargs={})
thread.deamon = True
thread.start()


def onMessage(self, author_id, message, thread_id, thread_type, **kwargs):
if author_id == self.uid:
def onMessage(self, message: SteelyMessage):
if message.author_id == self.uid:
return
if message is None or message == '':
if message.text is None or message.text == '':
# May occur when an image or sticker is sent.
return
self.run_non_plugins(author_id, message, thread_id,
thread_type, **kwargs)
self.run_plugin(author_id, message, thread_id, thread_type, **kwargs)

self.run_non_plugins(message)
self.run_plugin(message)


if __name__ == '__main__':
Expand Down
34 changes: 22 additions & 12 deletions steely/telegram_fbchat_facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from enum import Enum

from utils import new_database
from message import SteelyMessage

from tinydb import Query
from telegram import ParseMode, error as telegram_error
from telegram.ext import Updater, MessageHandler
from telegram import ParseMode, Update as TelegramUpdate, error as telegram_error
from telegram.ext import Updater, MessageHandler, CallbackContext
from telegram.ext.filters import Filters

ThreadType = Enum('ThreadType', 'USER GROUP')
Expand Down Expand Up @@ -110,20 +111,29 @@ def __init__(self, email, password):
self.thread = defaultdict(lambda: deque(iterable=[],
maxlen=Client.NUM_STORED_MESSAGES_IN_THREAD))

def _create_steely_message(self, author_id, text, thread_id, thread_type):
m = SteelyMessage()
m.author_id = author_id
m.text = text
m.thread_id = thread_id
m.thread_type = thread_type
return m

def listen(self):
def innerOnMessage(bot, update):
def innerOnMessage(update: TelegramUpdate, context: CallbackContext):
try:
print(update.message)
bot = context.bot
thread_id = update.effective_chat.id
thread_type = _telegram_chat_to_fbchat_thread_type(
update.effective_chat)
self.thread[thread_id].append(update.effective_message)
author_id = update.effective_user.id
self.thread[thread_id].append(update.effective_message)
self.user_manager.maybe_add_user(self.bot, thread_id, author_id)
self.onMessage(author_id=author_id,
message=update.effective_message.text,
thread_id=thread_id,
thread_type=thread_type)

message = self._create_steely_message(
author_id = author_id,
text = update.effective_message.text,
thread_id = thread_id,
thread_type = _telegram_chat_to_fbchat_thread_type(update.effective_chat))
self.onMessage(message)
except Exception as e:
log(e)
self.dispatcher.add_handler(MessageHandler(filters=Filters.all,
Expand Down Expand Up @@ -184,7 +194,7 @@ def sendLocalImage(self, image, thread_id, thread_type, message=None):
log(e)


def onMessage(self, author_id, message, thread_id, thread_type, **kwargs):
def onMessage(self, message: SteelyMessage):
'''Handler method; to be overriden.'''
pass

Expand Down