Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
OrBin committed Dec 19, 2022
2 parents cd0a72c + 6b2783f commit b8c06c8
Show file tree
Hide file tree
Showing 25 changed files with 85 additions and 96 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ If applicable, attach logs to help explain your problem.
If applicable, attach your configuration to help solve your problem.

**Desktop (please complete the following information):**
- OS and version: [e.g. Ubuntu 18.04]
- OS and version: [e.g. Ubuntu 22.04]
- Running environment:
- If running gramhopper inside a Docker container, please specify it.
- Python version [e.g. 3.7.1]
- Python version [e.g. 3.10.1]
- Version of gramhopper [e.g. 2.0.0]

**Additional context**
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[basic]
disable=missing-docstring, fixme
disable=missing-docstring, fixme, invalid-name

[design]
min-public-methods=1
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Please follow the bug report template (which appears when creating an issue) and
Look at issues tagged with [good first issue](https://github.com/OrBin/gramhopper/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+) label and find one you'd like to work on.

### How to build and test
We use [Invoke](http://docs.pyinvoke.org) CLI to execute development tasjs like test, build, lint, etc.
We use [Invoke](http://docs.pyinvoke.org) CLI to execute development tasks like test, build, lint, etc.

#### Building
To build, run:
Expand Down
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
FROM python:3.7-slim as builder
FROM python:3.10-alpine as builder

COPY . /app
WORKDIR /app/
RUN python setup.py bdist_wheel


FROM python:3.7-slim
# For some reason, ruamel.yaml won't be installed on alpine.
# That's not important enough to investigate, just leaving it with the slim image.
FROM python:3.10-slim

COPY --from=builder /app/dist/gramhopper-*.whl /
RUN pip install /gramhopper-*.whl && rm /gramhopper-*.whl
Expand Down
2 changes: 1 addition & 1 deletion gramhopper/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def start_bot():
args = parser.parse_args()
logging.debug(f'Parsed arguments: {args}')

with open(token_file_path(), 'r') as token_file:
with open(token_file_path(), 'r', encoding='utf-8') as token_file:
bot_token = token_file.read().strip()

rule_parser = RulesParser()
Expand Down
2 changes: 1 addition & 1 deletion gramhopper/configuration/boolean_helper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Callable
from boolean import boolean
from .partial_ruamel_yaml import CommentedMap
from ruamel.yaml import CommentedMap
from .boolean_operators import OPERATOR_TO_FUNCTION
from .common_types import TriggerOrResponse, GlobalsDict

Expand Down
22 changes: 0 additions & 22 deletions gramhopper/configuration/partial_ruamel_yaml.py

This file was deleted.

4 changes: 2 additions & 2 deletions gramhopper/configuration/rules_parser.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logging
from os import PathLike
from typing import Union, List
from .partial_ruamel_yaml import YAML
from .partial_ruamel_yaml import CommentedMap
from ruamel.yaml import YAML
from ruamel.yaml import CommentedMap
from .rules_parsing_helper import RulesParsingHelper
from ..handlers.rules_handler import RuleHandler
from .trigger_or_response_params import TriggerParams, ResponseParams
Expand Down
2 changes: 1 addition & 1 deletion gramhopper/configuration/rules_parsing_helper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .partial_ruamel_yaml import CommentedMap
from ruamel.yaml import CommentedMap
from .boolean_helper import BooleanHelper
from .common_types import TriggerOrResponse
from .trigger_or_response_params import TriggerOrResponseParams
Expand Down
2 changes: 1 addition & 1 deletion gramhopper/configuration/trigger_or_response_parser.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import abc
from typing import Dict, get_type_hints, Union, List, Any, Type
from inspect import isclass
from .partial_ruamel_yaml import CommentedMap, CommentedSeq
from ruamel.yaml import CommentedMap, CommentedSeq
from .common_types import TriggerOrResponse, GlobalsDict
from .boolean_helper import BooleanHelper
from ..dict_enum import DictEnum
Expand Down
8 changes: 4 additions & 4 deletions gramhopper/handlers/combined_handlers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from telegram.ext import MessageHandler, Filters, ConversationHandler

from telegram import Update
from telegram.ext import MessageHandler, Filters, ConversationHandler, CallbackContext

REGULAR_STATE = 0

Expand All @@ -11,9 +11,9 @@ def __init__(self, handlers):
self.handlers = handlers
super().__init__(Filters.all, self.handle_all)

def handle_all(self, bot, update):
def handle_all(self, update: Update, context: CallbackContext):
for handler in self.handlers:
handler.handle(bot, update)
handler.handle(update, context)
return REGULAR_STATE


Expand Down
5 changes: 3 additions & 2 deletions gramhopper/handlers/rules_handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import random
from telegram import Update, Bot
from telegram.ext import CallbackContext
from ..responses.basic_responses import BaseResponse
from ..triggers.basic_triggers import BaseTrigger

Expand Down Expand Up @@ -28,7 +29,7 @@ def __init__(self,

self.probability_to_respond = probability

def handle(self, bot: Bot, update: Update):
def handle(self, update: Update, context: CallbackContext):
logging.debug('[%s] Received update %s', self.handler_repr, update.update_id)
trigger_result = self.trigger_checker.check_trigger(update)
if trigger_result.should_respond:
Expand All @@ -38,4 +39,4 @@ def handle(self, bot: Bot, update: Update):
self.probability_to_respond)
if random.random() <= self.probability_to_respond:
logging.info('[%s] Responding to update %s', self.handler_repr, update.update_id)
self.responder.respond(bot, update, trigger_result.response_payload)
self.responder.respond(context.bot, update, trigger_result.response_payload)
20 changes: 7 additions & 13 deletions gramhopper/logging_config.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import logging
from .paths import log_file_path


def configure_logger():
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)

file_handler = logging.FileHandler(log_file_path())

# Create console handler with a higher log level
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.WARNING)

# Create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s %(module)s.%(funcName)s %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(
logging.Formatter(
'%(asctime)s %(module)s.%(funcName)s %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
)

# Add the handlers to the logger
root_logger.addHandler(file_handler)
root_logger.addHandler(console_handler)
5 changes: 0 additions & 5 deletions gramhopper/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
TOKEN_FILE_NAME = 'token.txt'
DEFAULT_RULES_FILE_NAME = 'rules.yml'
USERS_FILE_NAME = 'users.json'
LOG_FILE_NAME = 'gramhopper.log'


def token_file_path():
Expand All @@ -18,7 +17,3 @@ def default_rules_file_path():

def users_file_path():
return Path(CONFIG_DIR, USERS_FILE_NAME)


def log_file_path(file_name=LOG_FILE_NAME):
return Path(CONFIG_DIR, file_name)
4 changes: 2 additions & 2 deletions gramhopper/triggers/basic_triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class MergedTrigger(BaseTrigger):

def __init__(self,
base_trigger: BaseTrigger,
and_trigger: BaseTrigger = None,
or_trigger: BaseTrigger = None):
and_trigger: Optional[BaseTrigger] = None,
or_trigger: Optional[BaseTrigger] = None):
super().__init__()
self.base_trigger = base_trigger
self.and_trigger = and_trigger
Expand Down
17 changes: 12 additions & 5 deletions gramhopper/triggers/filter_triggers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from functools import reduce
from typing import List, Union
from typing import List, Union, Optional
from telegram import Update
from telegram.ext import Filters, BaseFilter
from ..dict_enum import DictEnum
Expand All @@ -24,7 +24,7 @@ def __init__(self, message_filter: BaseFilter):
self.filter = message_filter

def check_trigger(self, update: Update) -> TriggerResult:
return TriggerResult(should_respond=self.filter(update.message))
return TriggerResult(should_respond=self.filter(update))


class _UserFilterBasedTrigger(FilterBasedTrigger):
Expand All @@ -33,7 +33,12 @@ class _UserFilterBasedTrigger(FilterBasedTrigger):
specific user.
"""

def __init__(self, nickname: str = None, user_id: int = None, username: str = None):
def __init__(
self,
nickname: Optional[str] = None,
user_id: Optional[int] = None,
username: Optional[str] = None,
):
"""
Constructs the trigger.
`nickname` can be used if such a nickname is defined in users.json file.
Expand All @@ -56,7 +61,7 @@ class _ChatFilterBasedTrigger(FilterBasedTrigger):
chat.
"""

def __init__(self, chat_id: int = None, username: str = None):
def __init__(self, chat_id: Optional[int] = None, username: Optional[str] = None):
"""
Constructs the trigger.
One and only one of `chat_id` and `username` should be specified.
Expand Down Expand Up @@ -106,7 +111,9 @@ def __init__(self, message_type):
f'but it is a valid filter. Did you mean to use '
f'"{message_type}" as a filter type instead?')
except AttributeError:
raise ValueError(f'"{message_type}" is not a valid message type to filter by.')
raise ValueError( # pylint: disable=raise-missing-from
f'"{message_type}" is not a valid message type to filter by.'
)


class FilterTriggers(DictEnum):
Expand Down
6 changes: 4 additions & 2 deletions gramhopper/triggers/text_triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ def __init__(self, word: Union[str, List[str]]):
try:
super().__init__(word, exact=True)
except TypeError:
raise TypeError(f'Parameter \'word\' should be either a string or a list of strings '
f'({type(word)} given)')
raise TypeError( # pylint: disable=raise-missing-from
f'Parameter \'word\' should be either a string or a list of strings'
f' ({type(word)} given)'
)


class TextTriggers(DictEnum):
Expand Down
6 changes: 3 additions & 3 deletions gramhopper/users_helper.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import json
import os
from typing import Union
from typing import Optional
from .paths import users_file_path


class UsersHelper:
""" A helper for loading and reading users from the users file """

def __init__(self, file_path: Union[os.PathLike, str, bytes] = None):
def __init__(self, file_path: Optional[os.PathLike | str | bytes] = None):
if file_path is not None:
self.file_path = file_path
else:
Expand All @@ -19,7 +19,7 @@ def __init__(self, file_path: Union[os.PathLike, str, bytes] = None):
def load_users(self, force: bool = False):
if force or not self._users:
if os.path.exists(self.file_path):
with open(self.file_path, 'r') as file:
with open(self.file_path, 'r', encoding='utf-8') as file:
self._users = json.load(file)

def get_user_id_by_nickname(self, nickname: str) -> int:
Expand Down
21 changes: 11 additions & 10 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
python_telegram_bot==11.1.0
python_telegram_bot==13.15
boolean.py==3.6
ruamel_yaml~=0.15
sphinx==1.7.9
ruamel.yaml~=0.17
sphinx~=5.3.0
sphinx_rtd_theme==0.4.2
flaky==3.5.3
invoke==1.2.0
pytype==2019.9.6
pylint==2.3.1
flake8==3.7.8
pytest==5.1.2
wheel==0.37.1
flaky~=3.7.0
invoke~=1.7.3
pytype~=2022.12.15
pylint~=2.15.9
flake8~=6.0.0
pytest~=7.2.0
wheel==0.37.1
twine~=4.0.2
4 changes: 3 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[flake8]
max-line-length=100
ignore=E501 # Ignoring "E501 line too long" since pylint checks it
ignore=
# Ignoring "E501 line too long" since pylint checks it
E501,

[pytype]
disable=wrong-keyword-args
14 changes: 8 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from pathlib import Path
from setuptools import setup, find_namespace_packages

with open("README.md", "r") as f:
LONG_DESCRIPTION = f.read()

LONG_DESCRIPTION = Path("README.md").read_text(encoding='utf-8')


setup(
name='gramhopper',
version='2.1.0',
version='3.0.0',

description='A bot platform for automatic responses based on various triggers',
long_description=LONG_DESCRIPTION,
Expand All @@ -16,9 +18,9 @@
author='Or Bin, Meir Halachmi',
author_email='orbin50@gmail.com, meir.halachmi@gmail.com',
install_requires=[
'python_telegram_bot==11.1.0',
'python_telegram_bot==13.15',
'boolean.py==3.6',
'ruamel_yaml~=0.15'
'ruamel_yaml~=0.17'
],

license='MIT',
Expand All @@ -29,7 +31,7 @@
'Intended Audience :: Other Audience',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.10',
'Topic :: Communications :: Chat',
],

Expand Down
3 changes: 1 addition & 2 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ def lint(context):
exit_code = TASK_FAILURE_CODE

print('Running pytype...')
python_version = '%d.%d' % (sys.version_info.major, # pytype: disable=attribute-error
sys.version_info.minor) # pytype: disable=attribute-error
python_version = f'{sys.version_info.major}.{sys.version_info.minor}'
cmd = f'pytype --config ./setup.cfg -V {python_version} {source_code_dirs} {test_code_dirs}'
result = context.run(cmd, warn=True, echo=True)
if not result.exited == TASK_SUCCESS_CODE:
Expand Down

0 comments on commit b8c06c8

Please sign in to comment.