Skip to content

Commit

Permalink
Implement travis CI
Browse files Browse the repository at this point in the history
  • Loading branch information
vyahello committed Jan 20, 2020
1 parent cfa74ba commit a3772d1
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 90 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ venv

# python identifiers
.python-version
.pytest_cache/
.pytest_cache/
.coverage
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: python
python:
- "3.6"
- "3.7"
- "3.8"
before_install:
- pip install pip -U
- pip install -r requirements-dev.txt -U
script:
- ./analyse-code.sh
after_success:
- coveralls
notifications:
email: false
77 changes: 58 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,66 @@
# Guess the melody quiz game telegram bot
A quiz game telegram bot written in python with powerful [pyTelegramBotAPI](https://github.com/eternnoir/pyTelegramBotAPI) library.
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

## Run a quiz melody game telegram bot
[![Build Status](https://travis-ci.org/vyahello/guess-the-melody-bot.svg?branch=master)](https://travis-ci.org/vyahello/guess-the-melody-bot)
[![Coverage Status](https://coveralls.io/repos/github/vyahello/guess-the-melody-bot/badge.svg?branch=master)](https://coveralls.io/github/vyahello/guess-the-melody-bot?branch=master)
[![Forks](https://img.shields.io/github/forks/vyahello/guess-the-melody-bot)](https://github.com/vyahello/guess-the-melody-bot/network/members)
[![Stars](https://img.shields.io/github/stars/vyahello/guess-the-melody-bot)](https://github.com/vyahello/guess-the-melody-bot/stargazers)
[![Issues](https://img.shields.io/github/issues/vyahello/guess-the-melody-bot)](https://github.com/vyahello/guess-the-melody-bot/issues)
[![GitHub watchers](https://img.shields.io/github/watchers/vyahello/guess-the-melody-bot.svg)](https://GitHub.com/vyahello/guess-the-melody-bot/graphs/watchers/)
[![GitHub contributors](https://img.shields.io/github/contributors/vyahello/guess-the-melody-bot.svg)](https://GitHub.com/vyahello/guess-the-melody-bot/graphs/contributors/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE.md)

# Guess the melody telegram bot game
> A quiz telegram bot game written in python
>
> ![Screenshot](quiz/demo/bot.png)
## Tools
- python 3.6+
- [pyTelegramBotAPI](https://github.com/eternnoir/pyTelegramBotAPI)
- code analysis
- [pytest](https://pypi.org/project/pytest/)
- [black](https://black.readthedocs.io/en/stable/)

## Usage
Run script from the root directory of the project:
```bash
~ python quiz.py
➜ python -m quiz --run
Running quiz bot (press ctrl+c to escape)
...
```
Please specify your telegram `API key` to be able to use bot.

## Run unittests
Run script from the root directory of the project:
## Development notes

Project has Travis CI integration using [.travis.yml](.travis.yml) file thus code analysis (`black`) and unittests (`pytest`) will be run automatically
after every made change to the repository.

To be able to run code analysis, please execute command below:
```bash
~ pytest -s -v
➜ ./analyse-code.sh
```

## Demo
![Screenshot](bot.png)

# Contributing
- clone the repository
- configure Git for the first time after cloning with your name and email
```bash
git config --local user.name "Volodymyr Yahello"
git config --local user.email "vyahello@gmail.com"
```
- `python3.6` is required to run the code
- run `pip install -r requirements.txt` to install all required python packages
## Release notes

* 0.1.1
* Add Travis CI tool
* 0.1.0
* Distribute initial version on a bot

### Meta

Author – Volodymyr Yahello

Distributed under the `MIT` license. See [LICENSE](LICENSE.md) for more information.

You can reach out me at:
* [vyahello@gmail.com](vyahello@gmail.com)
* [https://github.com/vyahello](https://github.com/vyahello)
* [https://www.linkedin.com/in/volodymyr-yahello-821746127](https://www.linkedin.com/in/volodymyr-yahello-821746127)

### Contributing
1. clone the repository
2. configure Git for the first time after cloning with your `name` and `email`
3. `pip install -r requirements.txt` to install all project dependencies
4. `pip install -r requirements-dev.txt` to install all dev project dependencies
21 changes: 21 additions & 0 deletions analyse-code.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash

PACKAGE="quiz"


check-black() {
printf "Start black analysis ...\n" && ( black --check ${PACKAGE} )
}


check-unittests() {
printf "Start unittests analysis ...\n" && pytest
}


main() {
check-black && check-unittests
}


main
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[tool.black]
line-length = 120
target-version = ["py36", "py37", "py38"]
exclude = '''
/(
\.pytest_cache
)/
'''
7 changes: 7 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[pytest]
testpaths = tests/
python_files=*.py
python_functions=test_*
addopts = -rsxX
-v
--cov=quiz
5 changes: 0 additions & 5 deletions quiz.py

This file was deleted.

19 changes: 19 additions & 0 deletions quiz/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from typing import Any
import click
from bprint import bprint
from quiz.handler import bot


@click.command()
@click.option("--run", "-r", default=False, show_default=True, is_flag=True, help="Allows to run telegram bot app")
def main(run: bool, **kwargs: Any) -> None:
"""Runs telegram bot app."""
if run:
bprint("Running quiz bot (press ctrl+c to escape)")
bot.polling(none_stop=True, **kwargs)
else:
bprint("Nothing to run.")


if __name__ == "__main__":
main()
102 changes: 79 additions & 23 deletions quiz/bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,42 @@ class Bot(ABC):
"""Abstract interface for a bot."""

@abstractmethod
def message_handler(self, commands: Iterable[str] = None, regexp: str = None, func: Callable = None,
content_types: Iterable[str] = 'text', **kwargs: Any) -> Any:
def message_handler(
self,
commands: Iterable[str] = None,
regexp: str = None,
func: Callable = None,
content_types: Iterable[str] = "text",
**kwargs: Any,
) -> Any:
pass

@abstractmethod
def send_message(self, chat_id: int, text: str, disable_web_page_preview: bool = None,
reply_to_message_id: int = None, reply_markup: ReplyKeyboardRemove = None,
parse_mode: str = None, disable_notification: bool = None) -> Message:
def send_message(
self,
chat_id: int,
text: str,
disable_web_page_preview: bool = None,
reply_to_message_id: int = None,
reply_markup: ReplyKeyboardRemove = None,
parse_mode: str = None,
disable_notification: bool = None,
) -> Message:
pass

@abstractmethod
def send_voice(self, chat_id: int, voice: Any, caption: str = None, duration: int = None,
reply_to_message_id: int = None, reply_markup: ReplyKeyboardMarkup = None,
parse_mode: str = None, disable_notification: bool = None, timeout: int = None) -> VoiceMessage:
def send_voice(
self,
chat_id: int,
voice: Any,
caption: str = None,
duration: int = None,
reply_to_message_id: int = None,
reply_markup: ReplyKeyboardMarkup = None,
parse_mode: str = None,
disable_notification: bool = None,
timeout: int = None,
) -> VoiceMessage:
pass

@abstractmethod
Expand All @@ -37,24 +59,58 @@ class QuizBot(Bot):
def __init__(self) -> None:
self._bot: TeleBot = TeleBot(Config.token)

def message_handler(self, commands: Iterable[str] = None, regexp: str = None, func: Callable = None,
content_types: Iterable[str] = 'text', **kwargs: Any) -> Any:
def message_handler(
self,
commands: Iterable[str] = None,
regexp: str = None,
func: Callable = None,
content_types: Iterable[str] = "text",
**kwargs: Any,
) -> Any:

return self._bot.message_handler(commands, regexp, func, content_types, **kwargs)

def send_message(self, chat_id: int, text: str, disable_web_page_preview: bool = None,
reply_to_message_id: int = None, reply_markup: ReplyKeyboardRemove = None,
parse_mode: str = None, disable_notification: bool = None) -> Message:

return self._bot.send_message(chat_id, text, disable_notification, reply_to_message_id, reply_markup,
parse_mode, disable_notification)

def send_voice(self, chat_id: int, voice: Any, caption: str = None, duration: int = None,
reply_to_message_id: int = None, reply_markup: bool = None, parse_mode: str = None,
disable_notification: bool = None, timeout: int = None) -> VoiceMessage:

return BotVoiceMessage(self._bot.send_voice(chat_id, voice, caption, duration, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout))
def send_message(
self,
chat_id: int,
text: str,
disable_web_page_preview: bool = None,
reply_to_message_id: int = None,
reply_markup: ReplyKeyboardRemove = None,
parse_mode: str = None,
disable_notification: bool = None,
) -> Message:

return self._bot.send_message(
chat_id, text, disable_notification, reply_to_message_id, reply_markup, parse_mode, disable_notification
)

def send_voice(
self,
chat_id: int,
voice: Any,
caption: str = None,
duration: int = None,
reply_to_message_id: int = None,
reply_markup: bool = None,
parse_mode: str = None,
disable_notification: bool = None,
timeout: int = None,
) -> VoiceMessage:

return BotVoiceMessage(
self._bot.send_voice(
chat_id,
voice,
caption,
duration,
reply_to_message_id,
reply_markup,
parse_mode,
disable_notification,
timeout,
)
)

def polling(self, none_stop: bool = False, interval: int = 0, timeout: int = 20) -> None:
self._bot.polling(none_stop, interval, timeout)
26 changes: 10 additions & 16 deletions quiz/bot/navigation/keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,13 @@ def perform(self) -> ReplyKeyboardRemove:
class BotReplyKeyboardMarkup(MarkUp):
"""Bot keyboard markup implementation."""

def __init__(self, resize_keyboard: bool = None,
one_time_keyboard: bool = None,
selective: Any = None,
row_width: int = 3) -> None:
def __init__(
self, resize_keyboard: bool = None, one_time_keyboard: bool = None, selective: Any = None, row_width: int = 3
) -> None:

self._markup: ReplyKeyboardMarkup = ReplyKeyboardMarkup(resize_keyboard,
one_time_keyboard,
selective,
row_width)
self._markup: ReplyKeyboardMarkup = ReplyKeyboardMarkup(
resize_keyboard, one_time_keyboard, selective, row_width
)

def keyboard(self) -> ReplyKeyboardMarkup:
return self._markup
Expand All @@ -61,15 +59,11 @@ def add(self, item: str) -> None:
class BotReplyKeyboard(Keyboard):
"""Bot keyboard implementation."""

def __init__(self, resize_keyboard: bool=False,
one_time_keyboard: bool=True,
selective: Any=None,
row_width: int=1) -> None:
def __init__(
self, resize_keyboard: bool = False, one_time_keyboard: bool = True, selective: Any = None, row_width: int = 1
) -> None:

self._markup: MarkUp = BotReplyKeyboardMarkup(resize_keyboard,
one_time_keyboard,
selective,
row_width)
self._markup: MarkUp = BotReplyKeyboardMarkup(resize_keyboard, one_time_keyboard, selective, row_width)
self._remove: Action = BotRemoveKeyboard(selective)

def markup(self) -> MarkUp:
Expand Down
2 changes: 1 addition & 1 deletion quiz/bot/storage/pointer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ def execute(self, command: str) -> Cursor:
return self._conn.cursor().execute(command)

def fetch_all(self, command: str) -> List[Tuple[str]]:
return self.execute(command).fetchall()
return self.execute(command).fetchall()
2 changes: 1 addition & 1 deletion quiz/bot/storage/shelter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Shelter(ContextManager, DictAccess):
def __init__(self, config: Type[Config]) -> None:
self._shelter: DbfilenameShelf = open(config.shelve_name)

def __enter__(self) -> 'Shelter':
def __enter__(self) -> "Shelter":
return self

def __getitem__(self, item: str) -> int:
Expand Down
4 changes: 2 additions & 2 deletions quiz/bot/storage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ def __init__(self, config: Type[Config]) -> None:

def select_all(self) -> List[Tuple[str]]:
with self._conn:
return self._pointer.fetch_all('select * from {}'.format(self._table.name()))
return self._pointer.fetch_all("select * from {}".format(self._table.name()))

def select_single(self, row_num: int) -> Tuple[Any]:
with self._conn:
return self._pointer.fetch_all('select * from {} where id is {}'.format(self._table.name(), row_num))[0]
return self._pointer.fetch_all("select * from {} where id is {}".format(self._table.name(), row_num))[0]

def count_rows(self) -> int:
return len(self.select_all())
Expand Down
2 changes: 1 addition & 1 deletion quiz/bot/storage/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ def __init__(self, config: Type[Config]) -> None:
self._config = config

def name(self) -> str:
return self._config.db_name.split('.')[0]
return self._config.db_name.split(".")[0]

0 comments on commit a3772d1

Please sign in to comment.