383 lines
11 KiB
Python
383 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
import re
|
|
from collections import defaultdict
|
|
from math import ceil
|
|
|
|
import baas32
|
|
import telewalrus.bot
|
|
|
|
import api
|
|
import messages
|
|
|
|
|
|
from config import VIA_GROUPS, TG_TOKEN, USER_TOKENS
|
|
BOT = telewalrus.bot.Bot(TG_TOKEN)
|
|
|
|
|
|
class Database:
|
|
user_tokens = {}
|
|
group_ids = {}
|
|
|
|
@staticmethod
|
|
def load():
|
|
try:
|
|
f = open('database.json', 'r')
|
|
except OSError:
|
|
print('database does not exist, generating from config')
|
|
Database.user_tokens = USER_TOKENS
|
|
Database.group_ids = VIA_GROUPS
|
|
return
|
|
|
|
database = json.load(f)
|
|
|
|
Database.user_tokens = database.get('user_tokens') or USER_TOKENS
|
|
Database.group_ids = database.get('group_ids') or VIA_GROUPS
|
|
|
|
@staticmethod
|
|
def save():
|
|
database = {
|
|
'user_tokens': Database.user_tokens,
|
|
'group_ids': Database.group_ids
|
|
}
|
|
with open('database.json', 'w') as f:
|
|
json.dump(database, f, indent=4)
|
|
|
|
|
|
@BOT.command('start')
|
|
async def cmd_start(message):
|
|
name = message.from_user.first_name
|
|
if str(message.from_user.id) in Database.user_tokens:
|
|
await message.chat.message(
|
|
f'Welkom terug, {name}! Zie /tasks om te zien welke taken je open '
|
|
f'hebt staan.')
|
|
return
|
|
|
|
token = message.args.strip()
|
|
if not token:
|
|
await message.chat.message(
|
|
f'Hee hallo, {name}! Ik draai nog met de acceptatieversie van de via-site. '
|
|
f'Wil je me alsnog testen? Vraag dan even aan @sijman '
|
|
f'of hij je je API token wil geven. Dan kan je meteen aan de slag!')
|
|
return
|
|
|
|
try:
|
|
await api.test_token(token)
|
|
except api.PermissionDeniedError:
|
|
await message.chat.message(
|
|
f'Hallo, {name}! Helaas is dat geen geldige API token...')
|
|
|
|
Database.user_tokens[str(message.from_user.id)] = token
|
|
await message.chat.message(
|
|
f'Welkom, {name}! Zie /tasks om te zien welke taken je open hebt '
|
|
f'staan.')
|
|
|
|
|
|
@BOT.command('chatinfo')
|
|
async def cmd_chatinfo(message):
|
|
chat = message.chat
|
|
|
|
if message.chat.type == 'private':
|
|
admins = []
|
|
else:
|
|
admins = [admin.user for admin in await chat.administrators()]
|
|
|
|
msg = f'''
|
|
id: {chat.id}
|
|
type: {chat.type}
|
|
title: {chat.title}
|
|
username: {chat.username}
|
|
first_name: {chat.first_name}
|
|
last_name: {chat.last_name}
|
|
admins: {admins}
|
|
'''
|
|
await message.chat.message(msg)
|
|
|
|
|
|
@BOT.command('tasks')
|
|
async def cmd_tasks(message):
|
|
token = Database.user_tokens.get(str(message.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
is_group = message.chat.type != 'private'
|
|
if not is_group:
|
|
tasks = await api.get_tasks(token)
|
|
if not tasks:
|
|
await message.chat.message('Je hebt geen taken!')
|
|
return
|
|
else:
|
|
group_id = Database.group_ids.get(str(message.chat.id))
|
|
if group_id is None:
|
|
await message.chat.message(
|
|
'pimpy is nog niet ingeschakeld voor deze groep :/')
|
|
return
|
|
|
|
tasks = await api.get_group_user_tasks(token, group_id)
|
|
if not tasks:
|
|
await message.chat.message('Je hebt geen taken voor deze groep!')
|
|
return
|
|
|
|
msg = messages.tasks_message(tasks, is_group)
|
|
await message.chat.message(msg, parse_mode='HTML')
|
|
|
|
|
|
@BOT.command('grouptasks')
|
|
async def cmd_grouptasks(message):
|
|
token = Database.user_tokens.get(str(message.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
if message.chat.type == 'private':
|
|
await message.chat.message(
|
|
'Dit commando werkt alleen in commissiechats.')
|
|
return
|
|
|
|
group_id = Database.group_ids.get(str(message.chat.id))
|
|
if not group_id:
|
|
await message.chat.message(
|
|
'pimpy is nog niet ingeschakeld voor deze groep :/')
|
|
return
|
|
|
|
user_tasks = await api.get_group_tasks(token, group_id)
|
|
|
|
msg = ''
|
|
for i, (name, tasks) in enumerate(user_tasks.items()):
|
|
status = defaultdict(int)
|
|
for task in tasks:
|
|
status[task['status']] += 1
|
|
|
|
msg += f'<b>{name}</b>:\n' \
|
|
f' ⏸ {status["Niet begonnen"]}, ▶️ {status["Begonnen"]}, ' \
|
|
f'✅ {status["Done"]}, ❌ {status["Niet Done"]}\n'
|
|
|
|
users = await api.get_group_users(token, group_id)
|
|
keyboard = []
|
|
for i, user in enumerate(users):
|
|
if i % 3 == 0:
|
|
keyboard.append([])
|
|
|
|
keyboard[-1].append({
|
|
'text': user['name'],
|
|
'callback_data': f'tasks {user["id"]} {user["name"]}'
|
|
})
|
|
|
|
msg += '\nKlik op een naam hieronder om zijn/haar taken weer te geven.'
|
|
reply_markup = {'inline_keyboard': keyboard}
|
|
|
|
await message.chat.message(msg, parse_mode='HTML',
|
|
disable_web_page_preview=True,
|
|
reply_markup=json.dumps(reply_markup))
|
|
|
|
|
|
async def get_task_from_args(token, message, group_id=None):
|
|
task_code = baas32.normalize(message.args) if message.args else ''
|
|
if not task_code:
|
|
await message.chat.message(
|
|
'Welke taak? Protip: zet de taakcode achter het commando.')
|
|
return
|
|
|
|
try:
|
|
task_id = baas32.decode(task_code)
|
|
except ValueError:
|
|
await message.chat.message(f'{task_code} is geen geldige taakcode.')
|
|
return
|
|
|
|
try:
|
|
if group_id:
|
|
task = await api.get_group_task(token, group_id, task_id)
|
|
else:
|
|
task = await api.get_task(token, task_id)
|
|
except api.NotFoundError:
|
|
await message.chat.message(f'Kan taak {task_code} niet vinden :(')
|
|
return
|
|
except api.PermissionDeniedError:
|
|
await message.chat.message(
|
|
f'Je hebt geen rechten voor taak {task_code}.')
|
|
return
|
|
|
|
return task, task_code
|
|
|
|
|
|
@BOT.command('task')
|
|
async def cmd_task(message):
|
|
token = Database.user_tokens.get(str(message.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
group_id = None
|
|
if message.chat.type != 'private':
|
|
group_id = Database.group_ids.get(str(message.chat.id))
|
|
if not group_id:
|
|
await message.chat.message(
|
|
'pimpy is nog niet ingeschakeld voor deze groep :/')
|
|
return
|
|
|
|
task, _ = await get_task_from_args(token, message, group_id)
|
|
if not task:
|
|
return
|
|
|
|
msg, reply_markup = messages.task_message(task, group_id is not None)
|
|
|
|
await message.chat.message(msg, parse_mode='HTML',
|
|
reply_markup=json.dumps(reply_markup),
|
|
disable_web_page_preview=True)
|
|
|
|
|
|
@BOT.command('done')
|
|
async def cmd_done(message):
|
|
token = Database.user_tokens.get(str(message.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
group_id = None
|
|
if message.chat.type != 'private':
|
|
group_id = Database.group_ids.get(str(message.chat.id))
|
|
if not group_id:
|
|
await message.chat.message(
|
|
'pimpy is nog niet ingeschakeld voor deze groep :/')
|
|
return
|
|
|
|
task, task_code = await get_task_from_args(token, message, group_id)
|
|
if not task:
|
|
return
|
|
|
|
try:
|
|
await api.set_task_status(token, task['id'], 'done')
|
|
except api.PermissionDeniedError:
|
|
msg = f'Je mag taak <code>[{task_code}]</code> niet aanpassen!'
|
|
await message.chat.message(msg, parse_mode='HTML')
|
|
return
|
|
|
|
msg = f'Taak {task_code} staat nu op done!'
|
|
await message.chat.message(msg)
|
|
|
|
|
|
@BOT.command('actie')
|
|
async def cmd_actie(message):
|
|
token = Database.user_tokens.get(str(message.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
if message.chat.type == 'private':
|
|
await message.chat.message(
|
|
'Deze functie werkt alleen in commissiechats.')
|
|
return
|
|
|
|
group_id = Database.group_ids.get(str(message.chat.id))
|
|
if not group_id:
|
|
await message.chat.message(
|
|
'pimpy is nog niet ingeschakeld voor deze groep :/')
|
|
return
|
|
|
|
match = re.match(r'^([^:]+): (.*)$', message.args)
|
|
if not match:
|
|
match = re.match(r'^([^ ]+) (.*)$', message.args)
|
|
if match:
|
|
owner = match.group(1)
|
|
title = match.group(2)
|
|
await message.chat.message(
|
|
f'Incorrecte syntax. Misschien bedoelde je /actie {owner}: {title}?')
|
|
else:
|
|
await message.chat.message(
|
|
f'Incorrecte syntax. Probeer eens /actie [naam]: [titel].')
|
|
|
|
return
|
|
|
|
task = await api.add_group_task(
|
|
token, group_id, match.group(1), match.group(2))
|
|
msg, reply_markup = messages.task_message(task, True)
|
|
task_code = baas32.encode(task['id'])
|
|
msg = f'Taak <code>[{task_code}]</code> aangemaakt!\n\n' + msg
|
|
|
|
await message.chat.message(msg, parse_mode='HTML',
|
|
reply_markup=json.dumps(reply_markup),
|
|
disable_web_page_preview=True)
|
|
|
|
|
|
async def callback_status(query, _, args):
|
|
await query.answer()
|
|
|
|
token = Database.user_tokens.get(str(query.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
status, task_id = args
|
|
task_id = int(task_id)
|
|
|
|
if query.message.chat.type == 'private':
|
|
await api.set_task_status(token, task_id, status)
|
|
task = await api.get_task(token, task_id)
|
|
else:
|
|
group_id = VIA_GROUPS.get(query.message.chat.id)
|
|
if not group_id:
|
|
return
|
|
|
|
await api.set_group_task_status(token, group_id, task_id, status)
|
|
task = await api.get_group_task(token, group_id, task_id)
|
|
|
|
|
|
msg, reply_markup = messages.task_message(task, False)
|
|
await query.message.edit(msg, parse_mode='HTML',
|
|
reply_markup=json.dumps(reply_markup),
|
|
disable_web_page_preview=True)
|
|
|
|
|
|
async def callback_tasks(query, _, args):
|
|
await query.answer()
|
|
|
|
token = Database.user_tokens.get(str(query.from_user.id))
|
|
if not token:
|
|
msg = messages.stranger_message(message.from_user.first_name)
|
|
await message.chat.message(msg)
|
|
return
|
|
|
|
group_id = VIA_GROUPS.get(query.message.chat.id)
|
|
if not group_id:
|
|
return
|
|
|
|
user_id = int(args[0])
|
|
user_name = ' '.join(args[1:])
|
|
|
|
tasks = await api.get_group_user_tasks(token, group_id, user_id)
|
|
msg = messages.tasks_message(tasks, True, user_name)
|
|
await query.message.chat.message(msg, parse_mode='HTML',
|
|
disable_web_page_preview=True)
|
|
|
|
|
|
CALLBACK_HANDLERS = {
|
|
'status': callback_status,
|
|
'tasks': callback_tasks
|
|
}
|
|
|
|
@BOT.callback
|
|
async def callback(query):
|
|
command, *args = query.data.split(' ')
|
|
handler = CALLBACK_HANDLERS.get(command)
|
|
if handler:
|
|
await handler(query, command, args)
|
|
|
|
|
|
Database.load()
|
|
while True:
|
|
try:
|
|
BOT.run()
|
|
except KeyboardInterrupt:
|
|
print('\nsaving database')
|
|
Database.save()
|
|
print('hee doei hè')
|
|
break
|
|
except:
|
|
pass
|