Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v2.0.0: Bump python version to 3.12 and small improvements #27

Merged
merged 7 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,8 @@ on:
- '!main'

jobs:
changelog:
uses: obervinov/_templates/.github/workflows/changelog.yaml@v1.0.13

pylint:
uses: obervinov/_templates/.github/workflows/pylint.yaml@v1.0.13

pytest:
uses: obervinov/_templates/.github/workflows/pytest.yaml@v1.0.13
pr:
uses: obervinov/_templates/.github/workflows/pr.yaml@v2.0.0

pyproject:
uses: obervinov/_templates/.github/workflows/pyproject.yaml@v1.0.13
uses: obervinov/_templates/.github/workflows/pyproject.yaml@v2.0.0
17 changes: 2 additions & 15 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,5 @@ on:
- closed

jobs:
changelog:
uses: obervinov/_templates/.github/workflows/changelog.yaml@v1.0.13

pylint:
uses: obervinov/_templates/.github/workflows/pylint.yaml@v1.0.13

pytest:
uses: obervinov/_templates/.github/workflows/pytest.yaml@v1.0.13

pyproject:
uses: obervinov/_templates/.github/workflows/pyproject.yaml@v1.0.13

create-release:
uses: obervinov/_templates/.github/workflows/release.yaml@v1.0.13
needs: [changelog, pylint, pytest, pyproject]
release:
uses: obervinov/_templates/.github/workflows/release.yaml@v2.0.0
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).


## v2.0.0 - 2024-10-11
### What's Changed
**full changelog**: https://github.com/obervinov/messages-package/compare/v1.0.4..v2.0.0 by @ obervinov https://github.com/obervinov/messages-package/pull/27
#### 💥 Breaking Changes
* Bump python version to `3.12`
#### 📚 Bug Fixes
* [Fix invalid default path to messages.json ](https://github.com/obervinov/messages-package/issues/25)
#### 🚀 Features
* Bump workflows to `v2.0.0`
* [Add additional exceptions for more informative errors](https://github.com/obervinov/messages-package/issues/26)


## v1.0.4 - 2024-02-04
### What's Changed
**full changelog**: https://github.com/obervinov/messages-package/compare/v1.0.3...v1.0.4 by @ obervinov https://github.com/obervinov/messages-package/pull/24
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
## <img src="https://github.com/obervinov/_templates/blob/main/icons/book.png" width="25" title="about"> About this project
This package helps to easily and quickly generate beautiful messages for telegram bots using templates described in json.

## <img src="https://github.com/obervinov/_templates/blob/main/icons/github-actions.png" width="25" title="github-actions"> GitHub Actions
| Name | Version |
| ------------------------ | ----------- |
| GitHub Actions Templates | [v1.0.12](https://github.com/obervinov/_templates/tree/v1.0.12) |


## <img src="https://github.com/obervinov/_templates/blob/main/icons/requirements.png" width="25" title="functions"> Supported functions
Expand All @@ -37,8 +33,8 @@ name = myproject"
version = "1.0.0"

[tool.poetry.dependencies]
python = "^3.10"
messages = { git = "https://github.com/obervinov/messages-package.git", tag = "v1.0.3" }
python = "^3.12"
messages = { git = "https://github.com/obervinov/messages-package.git", tag = "v2.0.0" }

[build-system]
requires = ["poetry-core"]
Expand Down Expand Up @@ -125,3 +121,8 @@ _output result_
🏞 Messages from the queue have already been processed
[◾◾◾◾◾◾◾◾◾◾◾◾◾◾◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️◻️]19%
```

## <img src="https://github.com/obervinov/_templates/blob/main/icons/github-actions.png" width="25" title="github-actions"> GitHub Actions
| Name | Version |
| ------------------------ | ----------- |
| GitHub Actions Templates | [v2.0.0](https://github.com/obervinov/_templates/tree/v2.0.0) |
5 changes: 3 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ Versions supported to fix vulnerabilities

| Version | Supported |
| ------- | ------------------ |
| 1.0.x | :white_check_mark: |
| 2.x.x | :white_check_mark: |
| 1.x.x | :x: |

## Reporting a Vulnerability

In order to inform me about the vulnerability, write the details to the mail `github.obervinov@proton.me`
In order to inform me about the vulnerability, just create an issue: https://github.com/obervinov/messages-package/security/advisories/new
11 changes: 9 additions & 2 deletions messages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,12 @@
No need to add anything here. Feel free to delete this line when you make your own package
Leave it empty
"""
# flake8: noqa
from .messages import *
from .messages import Messages
from .exceptions import ConfigurationIsNotValid, TemplateNotFound, TemplatesIsNotValid

__all__ = [
'Messages',
'ConfigurationIsNotValid',
'TemplateNotFound',
'TemplatesIsNotValid'
]
1 change: 1 addition & 0 deletions messages/configs/messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"templates": {}}
30 changes: 30 additions & 0 deletions messages/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
This module contains custom exceptions that are used in the application.
"""


class ConfigurationIsNotValid(Exception):
"""
Exception raised when the configuration file is not valid JSON.
"""
def __init__(self, message):
self.message = message
super().__init__(self.message)


class TemplateNotFound(Exception):
"""
Exception raised when the template is not found in the configuration file.
"""
def __init__(self, message):
self.message = message
super().__init__(self.message)


class TemplatesIsNotValid(Exception):
"""
Exception raised when the templates is not valid.
"""
def __init__(self, message):
self.message = message
super().__init__(self.message)
113 changes: 76 additions & 37 deletions messages/messages.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,106 @@
"""
This module contains classes and methods
for assembling and sending telegram messages to the bot.
"""
"""This module contains classes and methods for assembling and sending telegram messages to the bot."""
import os
import json
import math
import re
from typing import Union
import emoji
from .exceptions import ConfigurationIsNotValid, TemplateNotFound, TemplatesIsNotValid


class Messages:
"""
This class contains methods
for assembling and sending telegram messages to the bot.
This class contains methods for assembling and sending telegram messages to the bot.

Attributes:
configuration (dict): the contents of the configuration file.

Exceptions:
ConfigurationIsNotValid: raised when the configuration file is not valid JSON.
TemplateNotFound: raised when the template is not found in the configuration file.
TemplatesIsNotValid: raised when the templates is not valid.

Examples:
>>> from messages import Messages
>>> messages = Messages('configs/messages.json')
>>> messages.render_template('test_message', username='pytest')
"""

def __init__(
self,
config_path: str = None
) -> None:
def __init__(self, config_path: str = 'configs/messages.json') -> None:
"""
Method for create a new messages instance.

Args:
config (str): the path as a file containing a dictionary with message templates.
"""
env_variable = os.environ.get("MESSAGES_CONFIG", None)

Returns:
None
if env_variable:
config_file = env_variable
else:
config_file = config_path

Examples:
>>> from messages import Messages
>>> messages = Messages('configs/messages.json')
self.configuration = self._read_configuration(config_file=config_file)

if not self._templates_is_valid():
raise TemplatesIsNotValid(
"Templates have invalid elements. Please check your configuration file. "
"Otherwise, check examples: https://github.com/obervinov/messages-package?tab=readme-ov-file#-usage-examples"
)

def _read_configuration(self, config_file: str = None) -> dict:
"""
if os.environ.get("MESSAGES_CONFIG", None) is not None:
self.config_path = os.environ.get("MESSAGES_CONFIG", None)
elif config_path:
self.config_path = config_path
else:
self.config_path = 'configs/messages.json'
Method for checking the validity of the configuration file and reading its contents.

Args:
config_file (str): the path as a file containing a dictionary with message templates.

if os.path.exists(self.config_path):
with open(self.config_path, 'r', encoding='UTF-8') as config_json:
Returns:
dict: the contents of the configuration file.
"""
if os.path.exists(config_file):
with open(config_file, 'r', encoding='UTF-8') as config_json:
try:
self.data = json.load(config_json)
config_json.close()
return json.load(config_json)
except json.JSONDecodeError as json_error:
# pylint: disable=no-value-for-parameter
raise json.JSONDecodeError(
f"Configuration file {self.config_path} is not valid JSON: {json_error}\n"
raise ConfigurationIsNotValid(
"Configuration file structure is not valid JSON. Please check examples: "
"https://github.com/obervinov/messages-package?tab=readme-ov-file#-usage-examples"
)
) from json_error
else:
raise FileNotFoundError(f"Configuration file not found: {self.config_path}")
raise FileNotFoundError(f"Configuration file not found: {config_file}")

def _templates_is_valid(self) -> bool:
"""
Method for checking the validity of the templates in the configuration file.

Returns:
bool: True if the templates are valid, False otherwise.
"""
if 'templates' in self.configuration:
for template in self.configuration['templates'].values():
if 'text' not in template or 'args' not in template:
print(f"[Messages]: there are no text or args in template {template}")
return False
if not isinstance(template['text'], str) or not isinstance(template['args'], list):
print(f"[Messages]: text or args in template {template} has an invalid data type")
return False
args_provided = len(template['args'])
args_expected = len(re.findall(r"{.*?}", template['text']))
if args_provided != args_expected:
print(f"[Messages]: the number of arguments in the template {template} does nots match")
return False
return True

def render_template(
self,
template_alias: str = None,
**kwargs
) -> Union[str, None]:
) -> str | None:
"""
Method for reading the text from the configuration file.

Args:
template_alias (str): the name of the template key for extracting text from conifg.
template_alias (str): the name of the template key for extracting text from config.

Keyword Args:
**kwargs: passing additional parameters for message assembly.
Expand All @@ -78,7 +115,7 @@ def render_template(
>>> messages.render_template('test_message', username='pytest')
"""
try:
template = self.data['templates'][template_alias]
template = self.configuration['templates'][template_alias]
arguments = []
for arg in template['args']:
if re.match(r":.*:", arg):
Expand All @@ -89,15 +126,17 @@ def render_template(
arguments.append(kwargs.get(arg))
# Building full message
return template['text'].format(*arguments)
except KeyError:
except KeyError as error:
print(f"[Messages]: template not found: {template_alias}")
return None
raise TemplateNotFound(
"Template not found in the configuration file. Please check your configuration file."
) from error

def render_progressbar(
self,
total_count: int = 0,
current_count: int = 0
) -> Union[str, None]:
) -> str | None:
"""
A Method for generating string with a progress bar based
on the transmitted statistics data.
Expand Down
Loading
Loading