Compare commits

..

13 Commits

Author SHA1 Message Date
a458788841 Added device info and bot prefix
All checks were successful
Analysis / SonarCloud (pull_request) Successful in 41s
Tests / Build and Test (3.11) (pull_request) Successful in 1m17s
Tests / Build and Test (3.12) (pull_request) Successful in 1m58s
Tests / Build and Test (3.13) (pull_request) Successful in 1m21s
2025-01-04 18:01:49 +01:00
b76f727263 Replaced MatrixBot.config with MatrixBot.bot_config because .config is already used by smbl
All checks were successful
Analysis / SonarCloud (pull_request) Successful in 1m52s
Tests / Build and Test (3.11) (pull_request) Successful in 1m18s
Tests / Build and Test (3.12) (pull_request) Successful in 1m22s
Tests / Build and Test (3.13) (pull_request) Successful in 1m23s
2025-01-04 17:49:44 +01:00
kku
5a244f603d TEST: Publishing Action
All checks were successful
Analysis / SonarCloud (pull_request) Successful in 40s
Tests / Build and Test (3.11) (pull_request) Successful in 1m18s
Tests / Build and Test (3.12) (pull_request) Successful in 1m28s
Tests / Build and Test (3.13) (pull_request) Successful in 1m24s
2025-01-02 13:51:36 +01:00
kku
9bc4d0348d WIP: Matrix support (with SMBL) 2025-01-01 22:35:17 +01:00
kku
ae54bd5cce Bump version to 4.0.2
All checks were successful
Analysis / SonarCloud (push) Successful in 42s
Analysis / SonarCloud (pull_request) Successful in 39s
Tests / Build and Test (3.11) (pull_request) Successful in 1m19s
Tests / Build and Test (3.12) (pull_request) Successful in 1m22s
Tests / Build and Test (3.13) (pull_request) Successful in 1m23s
2024-12-31 11:16:16 +01:00
kku
9ce251d733 Added a quick README for examples (belongs to #60)
All checks were successful
Analysis / SonarCloud (push) Successful in 41s
2024-12-31 11:10:06 +01:00
kku
5dd873d683 Closes #61
All checks were successful
Analysis / SonarCloud (push) Successful in 1m1s
2024-12-31 11:07:24 +01:00
b47bcbe513 Update dependency mypy to v1.14.1
All checks were successful
Analysis / SonarCloud (pull_request) Successful in 35s
Tests / Build and Test (3.11) (pull_request) Successful in 1m14s
Tests / Build and Test (3.12) (pull_request) Successful in 1m37s
Tests / Build and Test (3.13) (pull_request) Successful in 1m22s
Analysis / SonarCloud (push) Successful in 47s
2024-12-30 19:17:40 +02:00
kku
bbbec75f91 Fixed naming conventions
All checks were successful
Analysis / SonarCloud (push) Successful in 44s
2024-12-29 19:27:42 +01:00
kku
94553b602e Fixed imports in examples 2024-12-29 16:27:58 +01:00
kku
3cdd6da506 Added typing_extensions to the dependencies
All checks were successful
Analysis / SonarCloud (push) Successful in 58s
Analysis / SonarCloud (pull_request) Successful in 37s
Tests / Build and Test (3.11) (pull_request) Successful in 1m21s
Tests / Build and Test (3.12) (pull_request) Successful in 1m27s
Tests / Build and Test (3.13) (pull_request) Successful in 1m49s
2024-12-29 16:06:45 +01:00
kku
d24e94b57e Tests are now for 3.11+
All checks were successful
Analysis / SonarCloud (push) Successful in 44s
2024-12-27 18:33:51 +01:00
95584c0e63 Slight documentation improvements
All checks were successful
Analysis / SonarCloud (push) Successful in 46s
2024-12-27 00:37:54 +01:00
16 changed files with 243 additions and 17 deletions

View File

@@ -0,0 +1,90 @@
name: Upload Python Package
on:
release:
types: [ published ]
permissions:
contents: read
jobs:
release-build:
runs-on: ubuntu-latest
container: catthehacker/ubuntu:act-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Build release distributions
run: |
python -m pip install build
python -m build
- name: Upload distributions
uses: christopherhx/gitea-upload-artifact@v4
with:
name: release-dists
path: dist/
gitea-publish:
runs-on: ubuntu-latest
container: catthehacker/ubuntu:act-latest
needs:
- release-build
permissions:
id-token: write
environment:
name: gitea
url: https://git.end-play.xyz/profitroll/-/packages/pypi/libbot
env:
GITHUB_WORKFLOW_REF: ${{ gitea.workflow_ref }}
INPUT_REPOSITORY_URL: https://git.end-play.xyz/api/packages/profitroll/pypi
steps:
- name: Retrieve release distributions
uses: christopherhx/gitea-download-artifact@v4
with:
name: release-dists
path: dist/
- name: Publish package distributions to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_GITEA_API_TOKEN }}
repository-url: https://git.end-play.xyz/api/packages/profitroll/pypi
pypi-publish:
runs-on: ubuntu-latest
container: catthehacker/ubuntu:act-latest
needs:
- release-build
permissions:
id-token: write
environment:
name: pypi
env:
GITHUB_WORKFLOW_REF: ${{ gitea.workflow_ref }}
steps:
- name: Retrieve release distributions
uses: christopherhx/gitea-download-artifact@v4
with:
name: release-dists
path: dist/
- name: Publish package distributions to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_PYPI_API_TOKEN }}

View File

@@ -15,7 +15,7 @@ jobs:
container: catthehacker/ubuntu:act-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: [ "3.11", "3.12", "3.13" ]
steps:
- uses: actions/checkout@v3

View File

@@ -36,19 +36,20 @@ pip install libbot[pycord,speed]
### Pyrogram
```python
from libbot.pyrogram import PyroClient
import sys
from libbot.pyrogram.classes import PyroClient
def main():
client = PyroClient(scheduler=scheduler)
client: PyroClient = PyroClient()
try:
client.run()
except KeyboardInterrupt:
print("Shutting down...")
finally:
if client.scheduler is not None:
client.scheduler.shutdown()
exit()
sys.exit()
if __name__ == "__main__":
@@ -58,29 +59,33 @@ if __name__ == "__main__":
### Pycord
```python
import asyncio
from asyncio import AbstractEventLoop
from discord import Intents
from libbot import sync
from libbot.pycord import PycordBot
from libbot.utils import config_get
from libbot.pycord.classes import PycordBot
async def main():
intents = Intents.default()
bot = PycordBot(intents=intents)
intents: Intents = Intents.default()
bot: PycordBot = PycordBot(intents=intents)
bot.load_extension("cogs")
try:
await bot.start(sync.config_get("bot_token", "bot"))
await bot.start(config_get("bot_token", "bot"))
except KeyboardInterrupt:
logger.warning("Shutting down...")
print("Shutting down...")
await bot.close()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop: AbstractEventLoop = asyncio.get_event_loop()
loop.run_until_complete(main())
```
## Config examples
For bot config examples please check the examples directory. Without a valid config file, the bot won't start at all, so you need to make sure the correct config file is used.
For bot config examples please check the examples directory. Without a valid config file, the bot won't start at all, so
you need to make sure the correct config file is used.

4
examples/README.md Normal file
View File

@@ -0,0 +1,4 @@
# Examples
If you're looking for Pyrogram usage examples, please take a look at
the [PyrogramBotBase](https://git.end-play.xyz/profitroll/PyrogramBotBase) repository.

View File

@@ -28,6 +28,7 @@ dependencies = { file = "requirements/_.txt" }
[tool.setuptools.dynamic.optional-dependencies]
dev = { file = "requirements/dev.txt" }
matrix = { file = "requirements/matrix.txt" }
pycord = { file = "requirements/pycord.txt" }
pyrogram = { file = "requirements/pyrogram.txt" }
speed = { file = "requirements/speed.txt" }

View File

@@ -1 +1,2 @@
aiofiles>=23.0.0
aiofiles>=23.0.0
typing-extensions~=4.12.2

View File

@@ -1,11 +1,12 @@
black==24.10.0
build==1.2.2.post1
isort==5.13.2
mypy==1.14.0
mypy==1.14.1
pylint==3.3.3
pytest-asyncio==0.25.0
pytest-cov==6.0.0
pytest==8.3.4
tox==4.23.2
twine==6.0.1
types-aiofiles==24.1.0.20241221
types-ujson==5.10.0.20240515

1
requirements/matrix.txt Normal file
View File

@@ -0,0 +1 @@
simplematrixbotlib~=2.12.1

View File

@@ -1,4 +1,4 @@
__version__ = "4.0.0"
__version__ = "4.0.2"
__license__ = "GPL3"
__author__ = "Profitroll"

View File

@@ -0,0 +1,2 @@
# This file is left empty on purpose
# Adding imports here will cause import errors when libbot[matrix] is not installed

View File

@@ -0,0 +1 @@
from .bot import MatrixBot

View File

@@ -0,0 +1,80 @@
import logging
from logging import Logger
from pathlib import Path
from typing import Dict, Any
from typing_extensions import override
from ... import __version__ as __libbot_version__
from ...i18n.classes import BotLocale
from ...utils import json_read
try:
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.schedulers.background import BackgroundScheduler
from simplematrixbotlib import Bot, Creds, Config
except ImportError as exc:
raise ImportError("You need to install libbot[matrix] in order to use this class.") from exc
logger: Logger = logging.getLogger(__name__)
class MatrixBot(Bot):
@override
def __init__(
self,
config: Dict[str, Any] | None = None,
config_path: str | Path = Path("config.json"),
locales_root: str | Path | None = None,
scheduler: AsyncIOScheduler | BackgroundScheduler | None = None,
smbl_creds: Creds = None,
smbl_config: Config = None,
):
self.bot_config: Dict[str, Any] = config if config is not None else json_read(config_path)
super().__init__(
creds=(
smbl_creds
if smbl_creds is not None
else Creds(
homeserver=self.bot_config["bot"]["homeserver"],
username=self.bot_config["bot"]["username"],
password=self.bot_config["bot"]["password"],
device_name=(
f"LibBotUniversal v{__libbot_version__}"
if "device_name" not in self.bot_config["bot"]
else self.bot_config["bot"]["device_name"]
),
)
),
config=smbl_config,
)
self.bot_prefix: str = (
"!" if "prefix" not in self.bot_config["bot"] else self.bot_config["bot"]["prefix"]
)
self.bot_locale: BotLocale = BotLocale(
default_locale=self.bot_config["locale"],
locales_root=(Path("locale") if locales_root is None else locales_root),
)
self.default_locale: str = self.bot_locale.default
self.locales: Dict[str, Any] = self.bot_locale.locales
self._ = self.bot_locale._
self.in_all_locales = self.bot_locale.in_all_locales
self.in_every_locale = self.bot_locale.in_every_locale
self.scheduler: AsyncIOScheduler | BackgroundScheduler | None = scheduler
@override
def run(
self, scheduler_start: bool = True, scheduler_shutdown: bool = True, scheduler_wait: bool = True
) -> None:
if self.scheduler is not None and scheduler_start:
self.scheduler.start()
super().run()
if self.scheduler is not None and scheduler_shutdown:
self.scheduler.shutdown(scheduler_wait)

View File

@@ -0,0 +1,2 @@
# This file is left empty on purpose
# Adding imports here will cause import errors when libbot[pycord] is not installed

View File

@@ -0,0 +1 @@
from .color import color_from_hex, hex_from_color

View File

@@ -0,0 +1,35 @@
from discord import Colour
def _int_from_hex(hex_string: str) -> int:
try:
return int(hex_string, base=16)
except Exception as exc:
raise ValueError("Input string must be a valid HEX code.") from exc
def _hex_from_int(color_int: int) -> str:
if not 0 <= color_int <= 0xFFFFFF:
raise ValueError("Color's value must be in the range 0 to 0xFFFFFF.")
return f"#{color_int:06x}"
def color_from_hex(hex_string: str) -> Colour:
"""Convert valid hexadecimal string to discord.Colour.
:param hex_string: Hexadecimal string to convert into Colour object
:type hex_string: str
:return: Colour object
"""
return Colour(_int_from_hex(hex_string))
def hex_from_color(color: Colour) -> str:
"""Convert discord.Colour to hexadecimal string.
:param color: Colour object to convert into the string
:type color: Colour
:return: Hexadecimal string in #XXXXXX format
"""
return _hex_from_int(color.value)

View File

@@ -0,0 +1,2 @@
# This file is left empty on purpose
# Adding imports here will cause import errors when libbot[pyrogram] is not installed