cleanup; antispam
This commit is contained in:
parent
aad42f059e
commit
eb969e9dfb
Binary file not shown.
BIN
lobster.ttf
BIN
lobster.ttf
Binary file not shown.
198
main.py
198
main.py
@ -5,43 +5,55 @@ import os
|
|||||||
import re
|
import re
|
||||||
import traceback
|
import traceback
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from hashlib import sha1
|
||||||
from html import escape
|
from html import escape
|
||||||
from queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from threading import Thread
|
from threading import Thread, Event
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
from uuid import uuid4
|
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
from redis import Redis
|
||||||
from telegram.error import Unauthorized, TelegramError
|
from telegram.error import Unauthorized, TelegramError
|
||||||
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackQueryHandler
|
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackQueryHandler, CallbackContext
|
||||||
from telegram import Message, Update, Bot, InlineKeyboardMarkup, InlineKeyboardButton, User, InputMediaPhoto, \
|
from telegram import Message, Update, Bot, InlineKeyboardMarkup, InlineKeyboardButton, User, InputMediaPhoto, \
|
||||||
InputMediaVideo, InputMediaAnimation, InputMediaAudio, InputMediaDocument
|
InputMediaVideo, InputMediaAnimation, InputMediaAudio, InputMediaDocument
|
||||||
|
|
||||||
from config import BOT_TOKEN, SENTRY_DSN, MANAGEMENT_CHAT, DEBUG
|
from config import BOT_TOKEN, SENTRY_DSN, MANAGEMENT_CHAT, DEBUG
|
||||||
from db import get_conn, Subscriber, PersistentMapping, commit
|
from db import get_conn, Subscriber, commit
|
||||||
from morj import draw_morj
|
|
||||||
from send_users_list import send_users_list
|
from send_users_list import send_users_list
|
||||||
from shepherd import draw_shepherd
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
sentry_sdk.init(dsn=SENTRY_DSN)
|
sentry_sdk.init(dsn=SENTRY_DSN)
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
|
redis = Redis()
|
||||||
|
|
||||||
MAX_MESSAGE_LENGTH = 4096
|
MAX_MESSAGE_LENGTH = 4096
|
||||||
MAX_CAPTION_LENGTH = 1024
|
MAX_CAPTION_LENGTH = 1024
|
||||||
|
|
||||||
|
|
||||||
|
def _antispam(args):
|
||||||
|
if not args:
|
||||||
|
return True
|
||||||
|
args = '|'.join(map(str, args))
|
||||||
|
digest = sha1(args.encode()).digest()
|
||||||
|
key = 'lono-' + digest.hex()
|
||||||
|
if redis.get(key):
|
||||||
|
return False
|
||||||
|
redis.set(key, '1', ex=30)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _notify_access_request(bot: Bot, user: User):
|
def _notify_access_request(bot: Bot, user: User):
|
||||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton('Добавить', callback_data=f'add {user.id}')]])
|
markup = InlineKeyboardMarkup([[InlineKeyboardButton('Добавить', callback_data=f'add {user.id}')]])
|
||||||
bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={user.id}">{escape(user.full_name)}</a> запросил доступ',
|
bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={user.id}">{escape(user.full_name)}</a> запросил доступ',
|
||||||
parse_mode='html', reply_markup=markup)
|
parse_mode='html', reply_markup=markup)
|
||||||
|
|
||||||
|
|
||||||
def welcome(bot: Bot, update: Update):
|
def welcome(update: Update, ctx: CallbackContext):
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
_add_user(bot, update.effective_user.id)
|
_add_user(ctx.bot, update.effective_user.id)
|
||||||
update.message.reply_text('Добро пожаловать (debug)')
|
update.message.reply_text('Добро пожаловать (debug)')
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -49,14 +61,14 @@ def welcome(bot: Bot, update: Update):
|
|||||||
update.message.reply_text('Вы уже являетесь участником ЛОНО')
|
update.message.reply_text('Вы уже являетесь участником ЛОНО')
|
||||||
else:
|
else:
|
||||||
update.message.reply_text('Пожалуйста, обратитесь к @lono_contactbot')
|
update.message.reply_text('Пожалуйста, обратитесь к @lono_contactbot')
|
||||||
_notify_access_request(bot, update.message.from_user)
|
_notify_access_request(ctx.bot, update.message.from_user)
|
||||||
|
|
||||||
|
|
||||||
def unsubscribe(bot: Bot, update: Update):
|
def unsubscribe(update: Update, ctx: CallbackContext):
|
||||||
user = _remove_user(update.message.chat_id)
|
user = _remove_user(update.message.chat_id)
|
||||||
update.message.reply_text('Вы были отписаны от бота. '
|
update.message.reply_text('Вы были отписаны от бота. '
|
||||||
'Обратитесь к @lono_contactbot если вы хотите подписаться снова.')
|
'Обратитесь к @lono_contactbot если вы хотите подписаться снова.')
|
||||||
bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={user.id}">{escape(user.name)}</a> отписался')
|
ctx.bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={user.id}">{escape(user.name)}</a> отписался')
|
||||||
|
|
||||||
|
|
||||||
def _add_user(bot, uid):
|
def _add_user(bot, uid):
|
||||||
@ -65,7 +77,7 @@ def _add_user(bot, uid):
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def add_user(bot: Bot, update: Update, groups=(), args=()):
|
def add_user(update: Update, ctx: CallbackContext, groups=(), args=()):
|
||||||
if update.callback_query:
|
if update.callback_query:
|
||||||
update.callback_query.answer()
|
update.callback_query.answer()
|
||||||
|
|
||||||
@ -78,7 +90,7 @@ def add_user(bot: Bot, update: Update, groups=(), args=()):
|
|||||||
elif update.message and update.message.reply_to_message and update.message.reply_to_message.forward_from:
|
elif update.message and update.message.reply_to_message and update.message.reply_to_message.forward_from:
|
||||||
uid = update.message.reply_to_message.forward_from.id
|
uid = update.message.reply_to_message.forward_from.id
|
||||||
else:
|
else:
|
||||||
return bot.send_message(MANAGEMENT_CHAT, 'Укажите ID пользователя или ответьте на его сообщение')
|
return ctx.bot.send_message(MANAGEMENT_CHAT, 'Укажите ID пользователя или ответьте на его сообщение')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
uid = int(uid)
|
uid = int(uid)
|
||||||
@ -86,14 +98,14 @@ def add_user(bot: Bot, update: Update, groups=(), args=()):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = _add_user(bot, uid)
|
user = _add_user(ctx.bot, uid)
|
||||||
if update.callback_query:
|
if update.callback_query:
|
||||||
update.callback_query.message.edit_reply_markup()
|
update.callback_query.message.edit_reply_markup()
|
||||||
bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={uid}">{escape(user.name)}</a> был добавлен',
|
ctx.bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={uid}">{escape(user.name)}</a> был добавлен',
|
||||||
parse_mode='html')
|
parse_mode='html')
|
||||||
bot.send_message(uid, 'Добро пожаловать. Снова.')
|
ctx.bot.send_message(uid, 'Добро пожаловать. Снова.')
|
||||||
except TelegramError as e:
|
except TelegramError as e:
|
||||||
bot.send_message(MANAGEMENT_CHAT, str(e))
|
ctx.bot.send_message(MANAGEMENT_CHAT, str(e))
|
||||||
|
|
||||||
|
|
||||||
def _remove_user(uid):
|
def _remove_user(uid):
|
||||||
@ -103,7 +115,7 @@ def _remove_user(uid):
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def remove_user(bot: Bot, update: Update, groups=(), args=()):
|
def remove_user(update: Update, ctx: CallbackContext, groups=(), args=()):
|
||||||
if update.callback_query:
|
if update.callback_query:
|
||||||
update.callback_query.answer()
|
update.callback_query.answer()
|
||||||
|
|
||||||
@ -116,7 +128,7 @@ def remove_user(bot: Bot, update: Update, groups=(), args=()):
|
|||||||
elif update.message and update.message.reply_to_message and update.message.reply_to_message.forward_from:
|
elif update.message and update.message.reply_to_message and update.message.reply_to_message.forward_from:
|
||||||
uid = update.message.reply_to_message.forward_from.id
|
uid = update.message.reply_to_message.forward_from.id
|
||||||
else:
|
else:
|
||||||
return bot.send_message(MANAGEMENT_CHAT, 'Укажите ID пользователя или ответьте на его сообщение')
|
return ctx.bot.send_message(MANAGEMENT_CHAT, 'Укажите ID пользователя или ответьте на его сообщение')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
uid = int(uid)
|
uid = int(uid)
|
||||||
@ -125,19 +137,19 @@ def remove_user(bot: Bot, update: Update, groups=(), args=()):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
user = _remove_user(uid)
|
user = _remove_user(uid)
|
||||||
bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={uid}">{escape(user.name)}</a> был удален',
|
ctx.bot.send_message(MANAGEMENT_CHAT, f'<a href="tg://user?id={uid}">{escape(user.name)}</a> был удален',
|
||||||
parse_mode='html')
|
parse_mode='html')
|
||||||
if update.callback_query:
|
if update.callback_query:
|
||||||
update.callback_query.message.edit_reply_markup()
|
update.callback_query.message.edit_reply_markup()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
bot.send_message(MANAGEMENT_CHAT, f'Пользователь id={uid} не был найден')
|
ctx.bot.send_message(MANAGEMENT_CHAT, f'Пользователь id={uid} не был найден')
|
||||||
|
|
||||||
|
|
||||||
def users(bot: Bot, update: Update):
|
def users(update: Update, ctx: CallbackContext):
|
||||||
send_users_list()
|
send_users_list()
|
||||||
|
|
||||||
|
|
||||||
def msg(bot: Bot, update: Update):
|
def msg(update: Update, ctx: CallbackContext):
|
||||||
queue.put(update.message)
|
queue.put(update.message)
|
||||||
|
|
||||||
|
|
||||||
@ -219,7 +231,7 @@ def _process_media_group(bot: Bot, messages: List[Message]):
|
|||||||
_remove_user(uid)
|
_remove_user(uid)
|
||||||
|
|
||||||
|
|
||||||
def users_list(bot: Bot, update: Update):
|
def users_list(update: Update, ctx: CallbackContext):
|
||||||
current_chat = update.effective_chat.id
|
current_chat = update.effective_chat.id
|
||||||
subs = conn.root.subscribers # type: Dict[int, Subscriber]
|
subs = conn.root.subscribers # type: Dict[int, Subscriber]
|
||||||
if current_chat not in subs:
|
if current_chat not in subs:
|
||||||
@ -238,22 +250,6 @@ def users_list(bot: Bot, update: Update):
|
|||||||
update.effective_message.reply_text('\n'.join(messages[i:i+40]), parse_mode='html')
|
update.effective_message.reply_text('\n'.join(messages[i:i+40]), parse_mode='html')
|
||||||
|
|
||||||
|
|
||||||
def morj(bot: Bot, update: Update):
|
|
||||||
text = update.effective_message.text[6:]
|
|
||||||
fname = '/tmp/morj{}.png'.format(uuid4())
|
|
||||||
draw_morj(text, fname)
|
|
||||||
update.effective_message.reply_photo(open(fname, 'rb'))
|
|
||||||
os.unlink(fname)
|
|
||||||
|
|
||||||
|
|
||||||
def shepherd(bot: Bot, update: Update):
|
|
||||||
text = update.effective_message.text[10:]
|
|
||||||
fname = '/tmp/shepherd{}.png'.format(uuid4())
|
|
||||||
draw_shepherd(text, fname)
|
|
||||||
update.effective_message.reply_photo(open(fname, 'rb'))
|
|
||||||
os.unlink(fname)
|
|
||||||
|
|
||||||
|
|
||||||
def _process_message(bot: Bot, m: Message):
|
def _process_message(bot: Bot, m: Message):
|
||||||
if m.sticker or m.animation:
|
if m.sticker or m.animation:
|
||||||
delta = datetime.now() - conn.root.last_media
|
delta = datetime.now() - conn.root.last_media
|
||||||
@ -282,8 +278,67 @@ def _process_message(bot: Bot, m: Message):
|
|||||||
if m.reply_to_message and m.reply_to_message.message_id in users[current_chat].messages_forward:
|
if m.reply_to_message and m.reply_to_message.message_id in users[current_chat].messages_forward:
|
||||||
reply_to_message_internal_id = users[current_chat].messages_forward[m.reply_to_message.message_id]
|
reply_to_message_internal_id = users[current_chat].messages_forward[m.reply_to_message.message_id]
|
||||||
|
|
||||||
|
func = None
|
||||||
|
args = []
|
||||||
|
kwargs = {}
|
||||||
|
if m.forward_date:
|
||||||
|
func = m.forward
|
||||||
|
elif hasattr(m, 'audio') and m.audio:
|
||||||
|
a = m.audio
|
||||||
|
func = bot.send_audio
|
||||||
|
args = [a.file_id, a.duration, a.performer, a.title, caption]
|
||||||
|
kwargs = dict(parse_mode='html')
|
||||||
|
elif hasattr(m, 'document') and m.document:
|
||||||
|
d = m.document
|
||||||
|
func = bot.send_document
|
||||||
|
args = [d.file_id, d.file_name, caption]
|
||||||
|
kwargs = dict(parse_mode='html')
|
||||||
|
elif hasattr(m, 'photo') and m.photo:
|
||||||
|
p = m.photo
|
||||||
|
func = bot.send_photo
|
||||||
|
args = [p[-1].file_id, caption]
|
||||||
|
kwargs = dict(parse_mode='html')
|
||||||
|
elif hasattr(m, 'sticker') and m.sticker:
|
||||||
|
s = m.sticker
|
||||||
|
func = bot.send_sticker
|
||||||
|
args = [s.file_id]
|
||||||
|
elif hasattr(m, 'video') and m.video:
|
||||||
|
v = m.video
|
||||||
|
func = bot.send_video
|
||||||
|
args = [v.file_id, v.duration, caption]
|
||||||
|
kwargs = dict(parse_mode='html')
|
||||||
|
elif hasattr(m, 'voice') and m.voice:
|
||||||
|
v = m.voice
|
||||||
|
func = bot.send_voice
|
||||||
|
args = [v.file_id, v.duration, caption]
|
||||||
|
kwargs = dict(parse_mode='html')
|
||||||
|
elif hasattr(m, 'video_note') and m.video_note:
|
||||||
|
vn = m.video_note
|
||||||
|
func = bot.send_video_note
|
||||||
|
args = [vn.file_id, vn.duration, vn.length]
|
||||||
|
elif hasattr(m, 'contact') and m.contact:
|
||||||
|
c = m.contact
|
||||||
|
func = bot.send_contact
|
||||||
|
args = [c.phone_number, c.first_name, c.last_name]
|
||||||
|
elif hasattr(m, 'location') and m.location:
|
||||||
|
l = m.location
|
||||||
|
func = bot.send_location
|
||||||
|
args = [l.latitude, l.longitude]
|
||||||
|
elif hasattr(m, 'venue') and m.venue:
|
||||||
|
v = m.venue
|
||||||
|
l = v.location
|
||||||
|
func = bot.send_venue
|
||||||
|
args = [l.latitude, l.longitude, v.title, v.address, v.foursquare_id]
|
||||||
|
elif hasattr(m, 'text') and m.text:
|
||||||
|
func = bot.send_message
|
||||||
|
args = [text, 'html']
|
||||||
|
|
||||||
|
if not _antispam(args):
|
||||||
|
return m.reply_text('Не вайпи', quote=True)
|
||||||
|
|
||||||
remove_uids = []
|
remove_uids = []
|
||||||
|
|
||||||
|
if func:
|
||||||
for uid, user in users.items():
|
for uid, user in users.items():
|
||||||
sleep(.02)
|
sleep(.02)
|
||||||
|
|
||||||
@ -292,50 +347,7 @@ def _process_message(bot: Bot, m: Message):
|
|||||||
reply_to_message_id = user.messages_reverse.get(reply_to_message_internal_id, None)
|
reply_to_message_id = user.messages_reverse.get(reply_to_message_internal_id, None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = None
|
r = func(*([uid] + args), **kwargs, reply_to_message_id=reply_to_message_id)
|
||||||
if m.forward_date:
|
|
||||||
r = m.forward(uid)
|
|
||||||
elif hasattr(m, 'audio') and m.audio:
|
|
||||||
a = m.audio
|
|
||||||
r = bot.send_audio(uid, a.file_id, a.duration, a.performer, a.title, caption,
|
|
||||||
reply_to_message_id=reply_to_message_id, parse_mode='html')
|
|
||||||
elif hasattr(m, 'document') and m.document:
|
|
||||||
d = m.document
|
|
||||||
r = bot.send_document(uid, d.file_id, d.file_name, caption, reply_to_message_id=reply_to_message_id,
|
|
||||||
parse_mode='html')
|
|
||||||
elif hasattr(m, 'photo') and m.photo:
|
|
||||||
p = m.photo
|
|
||||||
r = bot.send_photo(uid, p[-1].file_id, caption, reply_to_message_id=reply_to_message_id,
|
|
||||||
parse_mode='html')
|
|
||||||
elif hasattr(m, 'sticker') and m.sticker:
|
|
||||||
s = m.sticker
|
|
||||||
r = bot.send_sticker(uid, s.file_id, reply_to_message_id=reply_to_message_id)
|
|
||||||
elif hasattr(m, 'video') and m.video:
|
|
||||||
v = m.video
|
|
||||||
r = bot.send_video(uid, v.file_id, v.duration, caption, reply_to_message_id=reply_to_message_id,
|
|
||||||
parse_mode='html')
|
|
||||||
elif hasattr(m, 'voice') and m.voice:
|
|
||||||
v = m.voice
|
|
||||||
r = bot.send_voice(uid, v.file_id, v.duration, caption, reply_to_message_id=reply_to_message_id,
|
|
||||||
parse_mode='html')
|
|
||||||
elif hasattr(m, 'video_note') and m.video_note:
|
|
||||||
vn = m.video_note
|
|
||||||
r = bot.send_video_note(uid, vn.file_id, vn.duration, vn.length,
|
|
||||||
reply_to_message_id=reply_to_message_id)
|
|
||||||
elif hasattr(m, 'contact') and m.contact:
|
|
||||||
c = m.contact
|
|
||||||
r = bot.send_contact(uid, c.phone_number, c.first_name, c.last_name,
|
|
||||||
reply_to_message_id=reply_to_message_id)
|
|
||||||
elif hasattr(m, 'location') and m.location:
|
|
||||||
l = m.location
|
|
||||||
r = bot.send_location(uid, l.latitude, l.longitude, reply_to_message_id=reply_to_message_id)
|
|
||||||
elif hasattr(m, 'venue') and m.venue:
|
|
||||||
v = m.venue
|
|
||||||
l = v.location
|
|
||||||
r = bot.send_venue(uid, l.latitude, l.longitude, v.title, v.address, v.foursquare_id,
|
|
||||||
reply_to_message_id=reply_to_message_id)
|
|
||||||
elif hasattr(m, 'text') and m.text:
|
|
||||||
r = bot.send_message(uid, text, 'html', reply_to_message_id=reply_to_message_id)
|
|
||||||
if r:
|
if r:
|
||||||
user.update_from_message(r)
|
user.update_from_message(r)
|
||||||
user.messages_forward[r.message_id] = conn.root.counter
|
user.messages_forward[r.message_id] = conn.root.counter
|
||||||
@ -353,9 +365,9 @@ def _process_message(bot: Bot, m: Message):
|
|||||||
_remove_user(uid)
|
_remove_user(uid)
|
||||||
|
|
||||||
|
|
||||||
def task_queue(u: Updater):
|
def task_queue(u: Updater, stop_signal: Event):
|
||||||
while True:
|
while True:
|
||||||
if not u.running:
|
if not u.running or stop_signal.is_set():
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -375,8 +387,8 @@ def task_queue(u: Updater):
|
|||||||
sentry_sdk.capture_exception()
|
sentry_sdk.capture_exception()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def main():
|
||||||
updater = Updater(BOT_TOKEN, workers=4)
|
updater = Updater(BOT_TOKEN, workers=4, use_context=True)
|
||||||
|
|
||||||
updater.dispatcher.add_handler(CommandHandler('start', welcome, Filters.private))
|
updater.dispatcher.add_handler(CommandHandler('start', welcome, Filters.private))
|
||||||
updater.dispatcher.add_handler(CommandHandler('stop', unsubscribe, Filters.private))
|
updater.dispatcher.add_handler(CommandHandler('stop', unsubscribe, Filters.private))
|
||||||
@ -385,17 +397,21 @@ if __name__ == '__main__':
|
|||||||
updater.dispatcher.add_handler(CommandHandler('remove', remove_user, Filters.chat(MANAGEMENT_CHAT), pass_args=True))
|
updater.dispatcher.add_handler(CommandHandler('remove', remove_user, Filters.chat(MANAGEMENT_CHAT), pass_args=True))
|
||||||
updater.dispatcher.add_handler(CallbackQueryHandler(remove_user, pattern=r'^remove (\d+)$', pass_groups=True))
|
updater.dispatcher.add_handler(CallbackQueryHandler(remove_user, pattern=r'^remove (\d+)$', pass_groups=True))
|
||||||
updater.dispatcher.add_handler(CommandHandler('users', users_list, Filters.private))
|
updater.dispatcher.add_handler(CommandHandler('users', users_list, Filters.private))
|
||||||
updater.dispatcher.add_handler(CommandHandler('morj', morj))
|
|
||||||
updater.dispatcher.add_handler(CommandHandler('shepherd', shepherd))
|
|
||||||
updater.dispatcher.add_handler(MessageHandler(Filters.private, msg))
|
updater.dispatcher.add_handler(MessageHandler(Filters.private, msg))
|
||||||
|
|
||||||
updater.start_polling()
|
updater.start_polling()
|
||||||
|
|
||||||
tq = Thread(target=task_queue, args=(updater,))
|
stop_signal = Event()
|
||||||
|
tq = Thread(target=task_queue, args=(updater, stop_signal))
|
||||||
tq.start()
|
tq.start()
|
||||||
|
|
||||||
logging.warning('LONO has started')
|
logging.warning('LONO has started')
|
||||||
updater.idle()
|
updater.idle()
|
||||||
|
stop_signal.set()
|
||||||
logging.warning('LONO is stopping...')
|
logging.warning('LONO is stopping...')
|
||||||
commit()
|
commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
10
morj.py
10
morj.py
@ -1,10 +0,0 @@
|
|||||||
from image_text import ImageText
|
|
||||||
|
|
||||||
FONT_FILE = 'CenturyGothicBold.ttf'
|
|
||||||
BG = 'MORJ.png'
|
|
||||||
|
|
||||||
|
|
||||||
def draw_morj(text, filename):
|
|
||||||
img = ImageText(BG)
|
|
||||||
img.write_text_box((67, 70), text, box_width=800, font_filename=FONT_FILE, font_size=40, color=(255, 255, 255))
|
|
||||||
img.save(filename)
|
|
BIN
shepherd.jpg
BIN
shepherd.jpg
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
11
shepherd.py
11
shepherd.py
@ -1,11 +0,0 @@
|
|||||||
from image_text import ImageText
|
|
||||||
|
|
||||||
FONT_FILE = 'lobster.ttf'
|
|
||||||
BG = 'shepherd.jpg'
|
|
||||||
|
|
||||||
|
|
||||||
def draw_shepherd(text, filename):
|
|
||||||
img = ImageText(BG)
|
|
||||||
img.write_text_box((74, 310), text, box_width=600, font_filename=FONT_FILE, font_size=40, color=(0, 0, 0),
|
|
||||||
place='center')
|
|
||||||
img.save(filename)
|
|
Loading…
Reference in New Issue
Block a user