Skip to content

Commit

Permalink
[refactoring] tests + contrib
Browse files Browse the repository at this point in the history
  • Loading branch information
AidarAzizov committed Apr 9, 2024
1 parent 50a6c87 commit 146cdc7
Show file tree
Hide file tree
Showing 24 changed files with 19,983 additions and 73 deletions.
15 changes: 10 additions & 5 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.11"]

steps:
- uses: actions/checkout@v3
Expand All @@ -27,14 +27,19 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python setup.py install
python -m pip install flake8 pytest
python -m pip install pytest-cov
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
flake8 --count --max-complexity="14" --doctests --show-source --statistics --max-line-length="125"
- name: Test with pytest
run: |
pytest
pytest --cov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
files: .coverage
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
# Compiled, optimized or cached files.
.cache/
__pycache__/
.pytest_cache/
*.py[cod]
*$py.class
build/

# Bot example log.
/example/log/
Expand Down
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Contribute
## Pull request
Если вы решили впервые стать контрибьютером и помочь развитию open-source проекта, этот пункт для вас.
1) Делается fork основного репозитория
2) git clone https://github.com/ваш-логин/bot-golang.git
3) Локальное изменение
4) Сделайте ребейз на remote master ветку
5) git push origin <ваш-логин>
6) В удаленном репозитории нажать _compare&pull request_

Также рекомендуем ознакомиться с подробной инструкцией для контрибьютеров - <a href="https://github.com/firstcontributions/first-contributions">README.md</a>

## Tests
1) Если добавляется новая функциональность, то покрывайте ее тестами
2) Следите за тем, чтобы тесты успешно выполнялись в PR перед мержем.

## Merge
Ветка будет смержена в мастер, когда:
1) Все пайплайны пройдут успешно
2) Новая функциональность будет покрыта тестами

После выполнения всех пунктов один из сотрудников проверит в ближайшее время PR и смержит его.
43 changes: 13 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
<img src="https://github.com/mail-ru-im/bot-python/blob/master/logo.png" width="100" height="100">
<img src="logo_bot.png" width="100" height="100">

# 🐍 bot-python
# VK Teams Bot API for Python
[![Python package](https://github.com/mail-ru-im/bot-python/actions/workflows/python-package.yml/badge.svg)](https://github.com/mail-ru-im/bot-python/actions/workflows/python-package.yml)
[![codecov](https://codecov.io/github/mail-ru-im/bot-python/graph/badge.svg?token=ObUFRWSyGv)](https://codecov.io/github/mail-ru-im/bot-python)
[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/mail-ru-im/bot-golang)
![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)

Pure Python interface for Bot API.
### [<img src="logo_msg.png" width="16"> VK Teams API Specification](https://teams.vk.com/botapi/)

# Table of contents
- [Introduction](#introduction)
- [Getting started](#getting-started)
- [Installing](#installing)
- [API description](#api-description)
## Getting started

# Introduction

This library provides complete Bot API 1.0 interface and compatible with Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10.

# Getting started

* Create your own bot by sending the /newbot command to <a href="https://icq.com/people/70001">Metabot</a> and follow the instructions.
* Create your own bot by sending the _/newbot_ command to _Metabot_ and follow the instructions.
>Note: a bot can only reply after the user has added it to his contact list, or if the user was the first to start a dialogue.
* You can configure the domain that hosts your ICQ server. When instantiating the Bot class, add the address of your domain.
> Example: Bot(token=TOKEN, name=NAME, version=VERSION, api_url_base="https://api.icq.net/bot/v1"), by default we use the domain: https://api.icq.net/bot/v1
* If you are Myteam client, you can add flag "is_myteam=True", when instantiating the Bot class. This will let you use additional chat methods.
> Example: Bot(token=TOKEN, name=NAME, is_myteam=True), by default it is False.
* You can configure the domain that hosts your VK Teams server. When instantiating the Bot class, add the address of your domain.
* An example of how to use the framework can be seen in _example/test_bot.py_

> An example of how to use the framework can be seen in example/test_bot.py
# Installing
## Installing
Install using pip:
```bash
pip install --upgrade mailru-im-bot
Expand All @@ -37,10 +26,4 @@ Install from sources:
git clone https://github.com/mail-ru-im/bot-python.git
cd bot-python
python setup.py install
```

# API description
<ul>
<li><a href="https://icq.com/botapi/">icq.com/botapi/</a></li>
<li><a href="https://agent.mail.ru/botapi/">agent.mail.ru/botapi/</a></li>
</ul>
```
17 changes: 14 additions & 3 deletions bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
from . import __version__ as version
from .dispatcher import Dispatcher
from .event import Event
from .handler import *
from .handler import EventType, DefaultHandler, \
NewChatMembersHandler, LeftChatMembersHandler, \
PinnedMessageHandler, MessageHandler, \
EditedMessageHandler, DeletedMessageHandler, \
CommandHandler, HelpCommandHandler, \
StartCommandHandler, UnknownCommandHandler, \
BotButtonCommandHandler, UnPinnedMessageHandler, \
Filter, StopDispatching
from .util import signal_name_by_code
from .myteam import add_chat_members, create_chat
from .types import InlineKeyboardMarkup, Format
Expand All @@ -32,6 +39,7 @@ def keyboard_to_json(keyboard_markup):
else:
return keyboard_markup


def format_to_json(format_):
if isinstance(format_, Format):
return format_.to_json()
Expand All @@ -40,6 +48,7 @@ def format_to_json(format_):
else:
return format_


class Bot(object):
def __init__(self, token: str, api_url_base: str = None, name: str = None, version: str = None,
timeout_s: int = 20, poll_time_s: int = 60, is_myteam: bool = False):
Expand Down Expand Up @@ -107,8 +116,10 @@ def _start_polling(self):
if "description" in response.json() and response.json()["description"] == 'Invalid token':
raise InvalidToken(response.json())

for event in response.json()["events"]:
self.dispatcher.dispatch(Event(type_=EventType(event["type"]), data=event["payload"]))
if "events" in response.json():
for event in response.json()["events"]:
self.dispatcher.dispatch(Event(type_=EventType(event["type"]), data=event["payload"]))

except InvalidToken as e:
self.log.exception("InvalidToken: {e}".format(e=e))
sleep(5)
Expand Down
2 changes: 2 additions & 0 deletions bot/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ class ChatType(Enum):
GROUP = "group"
CHANNEL = "channel"


@unique
class ParseMode(Enum):
MARKDOWNV2 = "MarkdownV2"
HTML = "HTML"


@unique
class StyleType(Enum):
BOLD = "bold"
Expand Down
2 changes: 1 addition & 1 deletion bot/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ def __init__(self, type_, data):
self.chat_type = data['message']['chat']['type']
self.message_author = data['queryId'].split(':')[1]
self.queryId = data['queryId']

def __repr__(self):
return "Event(type='{self.type}', data='{self.data}')".format(self=self)
1 change: 0 additions & 1 deletion bot/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,3 @@ class Filter(object):
sender = SenderFilter
callback_data = CallbackDataFilter
callback_data_regexp = CallbackDataRegexpFilter

2 changes: 1 addition & 1 deletion bot/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,4 @@ def check(self, event, dispatcher):
return (
super(BotButtonCommandHandler, self).check(event=event, dispatcher=dispatcher) and
event.type is EventType.CALLBACK_QUERY
)
)
3 changes: 2 additions & 1 deletion bot/myteam.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from requests import Request


def add_chat_members(self, chat_id, members):
return self.http_session.get(
Expand All @@ -11,6 +11,7 @@ def add_chat_members(self, chat_id, members):
}
)


def create_chat(self, name, about="", rules="", members=[], public=False, join_moderation=False, default_role="member"):
return self.http_session.get(
url="{}/chats/createChat".format(self.api_base_url),
Expand Down
7 changes: 5 additions & 2 deletions bot/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .constant import StyleType


class JsonSerializable(object):

def to_json(self):
Expand Down Expand Up @@ -73,15 +74,16 @@ def to_json(self):
def to_dic(self):
return self.keyboard


class Style(Dictionaryable, JsonSerializable):

def __init__(self):
self.ranges = []

def add(self, offset, length, args=None):
range_ = { "offset": offset, "length": length }
range_ = {"offset": offset, "length": length}
if args is not None:
self.ranges.append({ **range_ , **args})
self.ranges.append({**range_, **args})
else:
self.ranges.append(range_)

Expand All @@ -91,6 +93,7 @@ def to_dic(self):
def to_json(self):
return json.dumps(self.ranges)


class Format(Dictionaryable, JsonSerializable):

def __init__(self):
Expand Down
20 changes: 0 additions & 20 deletions example/decorators_bot.py

This file was deleted.

2 changes: 1 addition & 1 deletion example/echo_bot.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from bot.bot import Bot
from bot.handler import MessageHandler

TOKEN = "" #your token here
TOKEN = "" # your token here

bot = Bot(token=TOKEN)

Expand Down
4 changes: 2 additions & 2 deletions example/format_bot.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from bot.bot import Bot
from bot.handler import MessageHandler
from bot.constant import ParseMode
from bot.types import Format

import logging.config

logging.config.fileConfig("logging.ini")

TOKEN = "" #your token here
TOKEN = "" # your token here

bot = Bot(token=TOKEN, api_url_base="")


def message_cb(bot, event):
bot.send_text(chat_id=event.from_chat, text="*_Hello_*", parse_mode="MarkdownV2")
bot.send_text(chat_id=event.from_chat, text="<s>|</s> World! <s>|</s>", parse_mode="HTML")
Expand Down
5 changes: 3 additions & 2 deletions example/test_bot.py → example/hidden_test_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
CommandHandler, NewChatMembersHandler, LeftChatMembersHandler, PinnedMessageHandler, UnPinnedMessageHandler, \
EditedMessageHandler, DeletedMessageHandler, StartCommandHandler, BotButtonCommandHandler


if sys.version_info[0] == 3:
from gtts import gTTS

Expand All @@ -23,7 +24,7 @@
OWNER = "XXXXXXXXX"
TEST_CHAT = "XXXXX"
TEST_USER = "XXXXX"
API_URL = "https://api.icq.net/bot/v1"
API_URL = "http://localhost:8080"


def start_cb(bot, event):
Expand Down Expand Up @@ -259,7 +260,7 @@ def main():
bot.dispatcher.add_handler(MessageHandler(filters=Filter.text, callback=message_cb))

# Handler with regexp filter
bot.dispatcher.add_handler(MessageHandler(filters=Filter.regexp("^\d*$"), callback=regexp_only_dig_cb))
bot.dispatcher.add_handler(MessageHandler(filters=Filter.regexp("^\\d*$"), callback=regexp_only_dig_cb))

# Handler for no media file. For example, text file
bot.dispatcher.add_handler(MessageHandler(filters=Filter.data, callback=file_cb))
Expand Down
4 changes: 2 additions & 2 deletions example/myteam_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

logging.config.fileConfig("logging.ini")

TOKEN = "" #your token here
TOKEN = "" # your token here

bot = Bot(token=TOKEN, api_url_base="", is_myteam=True)

Expand All @@ -17,7 +17,7 @@ def message_cb(bot, event):
bot.add_chat_members(chat_id=resp.json()['sn'], members=["[email protected]", "[email protected]", "[email protected]"])
bot.send_text(chat_id=resp.json()['sn'], text="Hello! And Goodbye!")
bot.delete_chat_members(chat_id=resp.json()['sn'], members=["[email protected]", "[email protected]"])
bot.send_text(chat_id=event.from_chat, text="Bye!")
bot.send_text(chat_id=event.from_chat, text="Bye!")


bot.dispatcher.add_handler(MessageHandler(callback=message_cb))
Expand Down
2 changes: 1 addition & 1 deletion example/scheduled_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import time
from bot.bot import Bot

TOKEN = "" #your toke here
TOKEN = "" # your toke here
bot = Bot(token=TOKEN)

chats_to_send_notifications = [
Expand Down
Loading

0 comments on commit 146cdc7

Please sign in to comment.