def new(message):
    msg = message.text.replace('/new', '', 1)
    args = msg.split('\n', 1)
    if len(args) == 2:
        title, description = msg.split('\n', 1)
    else:
        title, description = msg, ''

    if len(title) > 256:
        return bot.reply_to(message, f'Title should be less than 256 chars')
    if len(description) > 2048:
        return bot.reply_to(message,
                            f'Description should be less than 2048 chars')

    timestamp = time.time()

    task_id = db.incr(f'/tasks/chat_id/{message.chat.id}/last_task_id')

    task = {
        'title': title.strip().capitalize(),
        'description': description,
        'created': timestamp,
        'modified': timestamp,
        'status': Status.TODO,
        'assignee': '',  # task will be assigned, when someone take it
        'assignee_id': '',
    }

    db.hset(f'/tasks/chat_id/{message.chat.id}', task_id, encode(task))

    return bot.reply_to(message, f'Created new task with id /{task_id}')
def task(message):

    try:
        task_id = int(message.text.replace('/', '', 1).strip().split()[0])
    except Exception:
        bot.reply_to(message, "Wrong syntax!")

    response, keyboard = get_task(message.chat.id, message.from_user.id,
                                  message.from_user.username, task_id)
    return bot.send_message(message.chat.id,
                            response,
                            reply_to_message_id=message.message_id,
                            reply_markup=keyboard)
def done(message, task_id):
    if task_id:
        task = change_status_task(message.chat.id,
                                  message.from_user.id,
                                  message.from_user.username,
                                  task_id,
                                  status=Status.DONE)
        if task:
            return bot.reply_to(
                message, f'''Title: {task["title"]}
Status: {task["status"]}
Assignee: {task["assignee"]}
Description:
{task["description"]}''')
        return

    response, keyboard = get_tasks(message.chat.id, Status.DONE, 0)
    return bot.send_message(message.chat.id, response, reply_markup=keyboard)
def update(message):
    msg = message.text.replace('/update', '', 1)
    args = msg.split('\n', 2)

    if len(args) == 3:
        task_id, title, description = msg.split('\n', 2)
    else:
        task_id, title, description = args[0], args[1], ''

    timestamp = time.time()
    task_id = int(task_id)

    task = db.hget(f'/tasks/chat_id/{message.chat.id}', task_id)

    task = decode(task)
    task['title'] = title
    task['description'] = description
    task['modified'] = timestamp

    db.hset(f'/tasks/chat_id/{message.chat.id}', task_id, encode(task))
    return bot.reply_to(message, f'Modified task with id /{task_id}')
def export(message):
    with TemporaryFile() as f:
        last_task_id = db.get(f'/tasks/chat_id/{message.chat.id}/last_task_id')

        if not last_task_id:
            return bot.reply_to(message, "There are no records.")

        task, *_ = db.hmget(f'/tasks/chat_id/{message.chat.id}', last_task_id)

        fieldnames = sorted(['task_id'] + list(decode(task).keys()))
        f.write((','.join(fieldnames)).encode())

        for t in db.hscan_iter(f'/tasks/chat_id/{message.chat.id}'):
            f.write(b'\n')
            task = decode(t[1])
            task['task_id'] = t[0].decode()
            row = ','.join([str(task[field]) for field in fieldnames])
            f.write(row.encode('utf-8'))

        f.seek(0)

        bot.send_document(message.chat.id, f, caption='report.csv')
def start(message):
    return bot.reply_to(message, 'Here will be start message')
def help_msg(message):
    return bot.reply_to(message, HELP)