Commands refactoring

This commit is contained in:
REDNBLACK 2017-08-19 18:19:21 +03:00
parent ad94b406bd
commit d4200c08b7
18 changed files with 100 additions and 99 deletions

View File

@ -20,3 +20,6 @@ class AbstractEntity(ABC):
"""Returns True if the message was edited.
"""
return self.message.edit_date is not None
def __str__(self):
return str(self.__dict__)

View File

@ -1,3 +1,4 @@
import logging
from telegram import Update
from telegram.ext import Handler
from telegram.ext.dispatcher import run_async
@ -28,11 +29,17 @@ class CommandHandler(Handler):
@run_async
def handle(self, bot, update):
command = Command(update.message)
data = Command(update.message)
logging.debug(f"Incoming command: {data}")
try:
self.commands[command.name](bot, command)
except (IndexError, ValueError):
bot.send_message(chat_id=command.chat_id,
reply_to_message_id=command.message.message_id,
text='Invalid command! Type /help')
command = self.commands[data.name]
if command.bot is None:
command.bot = bot
command.execute(data)
except (KeyError, IndexError, ValueError):
bot.send_message(
chat_id=data.chat_id,
reply_to_message_id=data.message.message_id,
text='Invalid command! Type /help'
)

View File

@ -19,9 +19,9 @@ commands = {}
for clazz in Base.__subclasses__():
command_name = getattr(clazz, 'name')
command_aliases = getattr(clazz, 'aliases')
execute_method = getattr(clazz, 'execute')
instance = clazz()
if command_name is not None:
commands[command_name] = execute_method
commands[command_name] = instance
for command_alias in command_aliases:
commands[command_alias] = execute_method
commands[command_alias] = instance

View File

@ -5,20 +5,20 @@ from abc import ABC, abstractmethod
class Base(ABC):
name = None
aliases = []
bot = None
@staticmethod
@abstractmethod
def execute(bot, command):
def execute(self, command):
pass
@staticmethod
def reply(bot, command, message):
logging.debug("[Chat %s %s command] %s: %s" %
(command.chat_type,
command.chat_id,
command.name,
message))
def reply(self, command, text):
logging.debug("Command %s: %s" % (str(command), text))
bot.send_message(chat_id=command.chat_id,
reply_to_message_id=command.message.message_id,
text=message)
self.bot.send_message(
chat_id=command.chat_id,
reply_to_message_id=command.message.message_id,
text=text
)
def send_photo(self, command, photo):
self.bot.send_photo(chat_id=command.chat_id, photo=photo)

View File

@ -1,16 +1,16 @@
from .base import Base
import json
from urllib.request import urlopen
from src.config import encoding
class Boobs(Base):
name = 'boobs'
aliases = ['80085', '(.)(.)']
@staticmethod
def execute(bot, command):
def execute(self, command):
response = urlopen('http://api.oboobs.ru/noise/1')
data = json.loads(response.read().decode('utf-8'))
data = json.loads(response.read().decode(encoding))
url = 'http://media.oboobs.ru/' + data[0]['preview']
bot.send_photo(chat_id=command.chat_id, photo=url)
self.send_photo(command, photo=url)

View File

@ -1,6 +1,7 @@
from .base import Base
import json
from src.utils import random_element
from src.config import encoding
from urllib.request import urlopen
@ -8,16 +9,15 @@ class Borscht(Base):
name = 'borscht'
images = None
@staticmethod
def execute(bot, command):
if Borscht.images is None:
Borscht.images = Borscht.__preload()
def __init__(self):
super().__init__()
self.images = self.__preload()
bot.send_photo(chat_id=command.chat_id, photo=random_element(Borscht.images))
def execute(self, command):
self.send_photo(command, photo=random_element(Borscht.images))
@staticmethod
def __preload():
def __preload(self):
response = urlopen('https://api.cognitive.microsoft.com/bing/v5.0/images/search?q=%D0%B1%D0%BE%D1%80%D1%89&mkt=en-us&safe-search=strict&image-type=photo&subscription-key=dd95294bc02748a1ab5152d36fdbbdac')
data = json.loads(response.read().decode('utf-8'))
data = json.loads(response.read().decode(encoding))
return list(map(lambda e: e['contentUrl'], data['value']))

View File

@ -1,5 +1,6 @@
from .base import Base
import json
from src.config import encoding
from urllib.request import urlopen
@ -7,10 +8,9 @@ class Butts(Base):
name = 'butts'
aliases = ['(_._)', '(_*_)', '(Y)']
@staticmethod
def execute(bot, command):
def execute(self, command):
response = urlopen('http://api.obutts.ru/noise/1')
data = json.loads(response.read().decode('utf-8'))
data = json.loads(response.read().decode(encoding))
url = 'http://media.obutts.ru/' + data[0]['preview']
bot.send_photo(chat_id=command.chat_id, photo=url)
self.send_photo(command, photo=url)

View File

@ -5,20 +5,18 @@ from src.config import chance_repository
class Chance(Base):
name = 'chance'
@staticmethod
def execute(bot, command):
def execute(self, command):
if command.is_private():
return Chance.reply(bot, command, 'Command disabled for private chats')
return self.reply(command, 'Command disabled for private chats')
try:
new_chance = int(command.args[0])
if new_chance < 1 or new_chance > 50:
return Chance.reply(bot, command, 'Usage: /chance 1-50.')
return self.reply(command, 'Usage: /chance 1-50.')
old_chance = chance_repository.set(chat_id=command.chat_id, new_chance=new_chance)
Chance.reply(bot, command, 'Change chance from {} to {}'.format(old_chance, new_chance))
self.reply(command, 'Change chance from {} to {}'.format(old_chance, new_chance))
except (IndexError, ValueError):
Chance.reply(bot, command, 'Current chance: {}'
.format(chance_repository.get(command.chat_id)))
self.reply(command, 'Current chance: {}'.format(chance_repository.get(command.chat_id)))

View File

@ -5,12 +5,13 @@ from urllib.request import urlopen, Request
class Facepalm(Base):
name = 'facepalm'
aliases = ['o']
path = 'storage/facepalm.jpg'
headers = {'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"}
@staticmethod
def execute(bot, command):
req = Request("http://loremflickr.com/500/410/facepalm", headers={'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"})
output = open("storage/facepalm.jpg", "wb")
def execute(self, command):
req = Request("http://loremflickr.com/500/410/facepalm", headers=self.headers)
output = open(self.path, "wb")
output.write(urlopen(req).read())
output.close()
bot.send_photo(chat_id=command.chat_id, photo=open('storage/facepalm.jpg', 'rb'))
self.send_photo(command, photo=open(self.path, 'rb'))

View File

@ -5,7 +5,6 @@ from src.config import trigram_repository
class GetStats(Base):
name = 'get_stats'
@staticmethod
def execute(bot, command):
def execute(self, command):
pairs_count = trigram_repository.count(command.chat_id)
GetStats.reply(bot, command, 'Pairs: {}'.format(pairs_count))
self.reply(command, 'Pairs: {}'.format(pairs_count))

View File

@ -6,6 +6,5 @@ class Help(Base):
name = 'help'
text = read_to_string('resources/info/help.txt')
@staticmethod
def execute(bot, command):
Help.reply(bot, command, Help.text)
def execute(self, command):
self.reply(command, self.text)

View File

@ -6,10 +6,8 @@ class Meow(Base):
name = 'meow'
aliases = [':3', '=3']
@staticmethod
def execute(bot, command):
def execute(self, command):
opener = build_opener(HTTPRedirectHandler)
request = opener.open('http://thecatapi.com/api/images/get?format=src')
url = request.url
req = opener.open('http://thecatapi.com/api/images/get?format=src')
bot.send_photo(chat_id=command.chat_id, photo=url)
self.send_photo(command, photo=req.url)

View File

@ -4,13 +4,12 @@ from src.config import config, trigram_repository
class Moderate(Base):
aliases = ['mod_f', 'mod_d']
gods = [int(id) for id in config.getlist('bot', 'god_mode')]
gods = config.getlist('bot', 'god_mode', type=int)
@staticmethod
def execute(bot, command):
def execute(self, command):
try:
if not command.is_private() and not Moderate.is_admin(bot, command):
return Moderate.reply(bot, command, 'You don\'t have admin privileges!')
if not command.is_private() and not self.__is_admin(command):
return self.reply(command, 'You don\'t have admin privileges!')
if len(command.args) == 0:
raise IndexError
@ -18,20 +17,20 @@ class Moderate(Base):
if command.name == 'mod_f':
words = trigram_repository.find_word(command.chat_id, command.args[0].strip())
reply = '\n'.join(words)
if reply == '':
if reply.strip() == '':
reply = 'Nothing found'
Moderate.reply(bot, command, reply)
self.reply(command, reply)
elif command.name == 'mod_d':
trigram_repository.remove_word(command.chat_id, command.args[0].strip())
except (IndexError, ValueError):
Moderate.reply(bot, command, """Usage:
self.reply(command, """Usage:
/mod_f <similar_word> for search
/mod_d <exact_word> for deletion""")
@staticmethod
def is_admin(bot, entity):
def __is_admin(self, entity):
user_id = entity.message.from_user.id
admin_ids = list(map(lambda m: m.user.id, bot.get_chat_administrators(entity.chat_id)))
admin_ids = list(map(lambda m: m.user.id, self.bot.get_chat_administrators(entity.chat_id)))
return user_id in admin_ids or user_id in Moderate.gods
return user_id in admin_ids \
or user_id in self.gods

View File

@ -11,7 +11,6 @@ class Ping(Base):
'reply',
'pingback'
]
@staticmethod
def execute(bot, command):
Ping.reply(bot, command, random_element(Ping.answers))
def execute(self, command):
self.reply(command, random_element(Ping.answers))

View File

@ -4,6 +4,5 @@ from .base import Base
class Start(Base):
name = 'start'
@staticmethod
def execute(bot, command):
Start.reply(bot, command, 'Hi! :3')
def execute(self, command):
self.reply(command, 'Hi! :3')

View File

@ -4,16 +4,15 @@ from PIL import Image, ImageFont, ImageDraw
class Vzhuh(Base):
name = 'vzhuh'
path = 'storage/vzhuh.png'
@staticmethod
def execute(bot, command):
text = Vzhuh.format_text('вжух ' + ' '.join(command.args))
Vzhuh.create_image(text)
def execute(self, command):
text = self.__format_text('вжух ' + ' '.join(command.args))
self.__generate_image(text)
bot.send_photo(chat_id=command.chat_id, photo=open('storage/vzhuh.png', 'rb'))
self.send_photo(command, photo=open(self.path, 'rb'))
@staticmethod
def format_text(text):
def __format_text(self, text):
result = []
current_part = ''
if len(text) > 8:
@ -31,10 +30,9 @@ class Vzhuh(Base):
return '\n'.join(result)
@staticmethod
def create_image(text):
def __generate_image(self, text):
img = Image.open("resources/vzhuh/sample.png")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('resources/vzhuh/Impact.ttf', 44, index=0)
draw.text((222, 280), text, (0, 0, 0), font=font)
img.save('storage/vzhuh.png')
img.save(self.path)

View File

@ -4,12 +4,13 @@ from urllib.request import urlopen, Request
class Woof(Base):
name = 'woof'
path = 'storage/woof.jpg'
headers = {'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"}
@staticmethod
def execute(bot, command):
req = Request("http://loremflickr.com/500/410/dog", headers={'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"})
output = open("storage/woof.jpg", "wb")
def execute(self, command):
req = Request("http://loremflickr.com/500/410/dog", headers=self.headers)
output = open(self.path, "wb")
output.write(urlopen(req).read())
output.close()
bot.send_photo(chat_id=command.chat_id, photo=open('storage/woof.jpg', 'rb'))
self.send_photo(command, photo=open(self.path, 'rb'))

View File

@ -7,10 +7,10 @@ from urllib.request import urlopen
class XKCD(Base):
name = 'xkcd'
@staticmethod
def execute(bot, command):
def execute(self, command):
last_id = json.loads(urlopen("http://xkcd.com/info.0.json").read().decode('utf-8'))['num']
id = random.randint(1, last_id)
url = json.loads(urlopen('http://xkcd.com/' + str(id) + '/info.0.json').read().decode('utf-8'))['img']
random_id = random.randint(1, last_id)
req = urlopen('http://xkcd.com/%d/info.0.json' % random_id)
data = json.loads(req.read().decode('utf-8'))
bot.send_photo(chat_id=command.chat_id, photo=url)
self.send_photo(command, photo=data['img'])